首页 > 编程语言 >Java中for循环每次都通过list.size、str.length、length()获取数组或者字符串的长度是否消耗资源

Java中for循环每次都通过list.size、str.length、length()获取数组或者字符串的长度是否消耗资源

时间:2023-11-15 16:33:41浏览次数:41  
标签:Java int list length 数组 字符串 长度 size

最近看到有同事在使用for循环的时候首先会将数组或者字符串的长度赋值给一个变量;在网上查了一下说是这样可以节约资源的消耗,真实的情况又是如何?让我们看下他们的源码来分析。

1.将数组的长度赋值给变量len

        List<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(2);
        for(int i=0,len=list.size();i<len;i++) {
            System.out.println(list.get(i));
        }

将数组的长度赋值给len变量,这样不用每次循环都去调用size()方法;这样能不能节约资源那我们就看下源码是如何定义的:

    private int size;
    ...
     public int size() {
        return size;
    }
    //数组中新增元素
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    //数组中删除元素
    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

我们可以看到源码中定义了一个size变量,数组在新增或者删除元素的时候会直接修改这个变量的值,每次调用size方法的时候是直接去取size变量的,不会去重新计算数组的大小,所以对于list数组来说不会过多的消耗资源。

2.字符串类型的长度赋值给变量len

        String str = "asdf";
        for(int i=0,len=str.length();i<len;i++) {
            System.out.println(str.charAt(i));
        }

字符串的长度是要调用length方法获取,我们看下源码是如何操作的:

    /** The value is used for character storage. */
    private final char value[];
    ...
    /**
     * Returns the length of this string.
     * The length is equal to the number of <a href="Character.html#unicode">Unicode
     * code units</a> in the string.
     *
     * @return  the length of the sequence of characters represented by this
     *          object.
     */
    public int length() {
        return value.length;
    }

我们可以看到字符串的底层是存储在一个char类型的数组中的,获取字符串的长度每次都需要计算value数组中字符的个数,也就是数组的长度,循环每次都会计算,这样就会消耗额外的资源,所以建议字符串类型的定义一个变量存储字符串的长度。

3.数组类型计算长度length属性

首先数组是一个对象类型,数组一旦创建成功它的长度就固定了,所以它可以定义一个变量类型length属性来存储数组的长度,也就是说每次调用lengh属性的时候不会重新的计算数组的长度,也就不会过多的消耗资源;

数组在java里是一种特殊类型,有别于普通的“类的实例”对象,java里数组不是类,所以也就没有对应的class文件,数组类型是由jvm从元素类型合成出来的;在jvm中获取数组的长度是用arraylength这个专门的字节码指令的;

那你可能会问jvm中是如何获取数组的长度?

答案是在数组的对象头里有一个_length字段,记录数组长度,arraylength的实现只需要去读_length字段就可以了。

        String[] s = {"qw","as","a"};
        for(int i=0; i<s.length; i++) {
            System.out.println(s[i]);
        }

当我们对数组的length进行++操作的时候编译器会报The final field array.length cannot be assigned,说明这个变量是一个final类型的,不可以修改。

总结

根据上面的几种种情况,数组和List集合不会过多消耗资源,字符串长度for循环是会消耗多余资源,所以建议定义一个变量存储数组或者字符串长度,养成良好的习惯,这样可以避免不是很了解底层的实现方式的数组等for循环过多消耗资源。










标签:Java,int,list,length,数组,字符串,长度,size
From: https://blog.51cto.com/u_16071479/8398438

相关文章

  • java怎么和html结合
    Java和HTML结合通常是在Web开发的背景下进行的。Java可以用于后端服务器编程,而HTML用于前端界面设计。这两者结合主要通过以下几种方式:Servlet和JSP:Servlet:JavaServlet是运行在Web服务器或应用服务器上的程序,它接收来自Web浏览器的请求,并生成响应给浏览器。Servlet通常用......
  • 开发遇到的问题总结---返回的list顺序乱序
    问题描述:从数据库中查询json并转为list,然后做了一些处理之后返回发现顺序变了1.json转换为list对象时:这一步是根据json里面的顺序(不会改变顺序)2.中间将list转为map,然后根据map的keyset获取每个值做一些处理,处理完成增加到返回的list中(这一步会改变顺序,因为map的keyset是无序的,因......
  • java实现的数独游戏
    数独游戏:窗体+逻辑实现类importjavax.swing.*;importjava.awt.*;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;publicclassSudokuGameextendsJFrame{privateJTextField[][]cells;privateint[][]solution;private......
  • Java 四种引用类型(强引用、软引用、弱引用、虚引用)
    概述Java中的引用类似C语言中的指针,指向一个对象,比如://person就是指向Person实例“张三”的引用Personperson=newPerson("张三");在JDK1.2以前,Java里的引用是很传统的定义:如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称该referenc......
  • CentOS中查看Java进程
    1.ps命令:可以用来查看当前系统中正在运行的进程。要查看Java进程,可以使用以下命令:ps-ef|grepjava该命令会列出所有包含“java”关键字的进程信息。你可以通过查看进程的PID(进程ID)和其他详细信息来确定你要找的java进程。2.jps命令:是Java虚拟机(JVM)提供的一个工具,用于查看当......
  • Java Mysql 类型为Long 转 前端String
    一、背景JavaMysql类型为Long转前端会丢失精度,在原先基础上补0000;二、实现1.//@JsonSerialize(using=ToStringSerializer.class)但是对我这里是不生效的@JSONField(serializeUsing=com.alibaba.fastjson.serializer.ToStringSerializer.class)生效三、遇......
  • 超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。
    来源:juejin.cn/post/70233173515630018861、概述SpringBoot框架不用多介绍,Java程序员想必都知道。相对来说熟悉Quarkus的人可能会少一些。Quarkus首页放出的标语:超音速亚原子的Java(SupersonicSubatomicJava)。它是为OpenJDKHotSpot和GraalVM量身定制的KubernetesNative......
  • Collections工具类、(Arrasy.asList(xxx)的结果List是一个受限集合,不能添加和删除元素
     Arrasy.asList(arr)的结果List是一个受限集合,不能添加和删除元素  ......
  • 理解与使用Javascript中的回调函数
     js里的解释:Acallbackisafunctionthatispassedasanargumenttoanotherfunctionandisexecutedafteritsparentfunctionhascompleted.    从字面上理解下来就是,回调就是一个函数的调用过程。假如函数a有一个参数,这个参数是个函数b,当函数a执行完......
  • 如何用好java的lambda表达式
    Lambda表达式是Java8引入的一种新特性,它使得在Java中能够更加方便地使用函数式编程的思想。Lambda表达式可以简洁地表示一个匿名函数,可以作为参数传递给方法或者作为返回值返回。使用Lambda表达式可以使代码更加简洁、易读,并且能够更好地利用多核处理器的优势。Lambda表达式的基本......