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

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

1.数组.length

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

结论:纯属性,直接读取该数组的_length字段,遍历时频繁读取并不会消耗过多资源。

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

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

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

数组一旦定义,长度是不可以改变的

2.集合.size()

 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));
  }

结论:list数组不会过多的消耗资源

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

//JDK 1.8
public class ArrayList {
    
    
 transient Object[] elementData;   //实际存储对象的数组
 private int size;         //size成员变量
 public int size() {
    
    
      return size;        //直接返回size
  }

ArrayList 底层也是Object[]数组实现的,那么为何不直接调用elementData.length,而仍然要定义一个size属性?原因是数组长度是不可变的,一旦定义初始长度,后续无法修改,只能重新定义一个新的数组,elementData根据构造函数的initialCapacity参数设置初始大小,只不过每个位置上的元素为空,因此数组的长度不能代表实际元素的个数,因此由size属性负责。

3.字符串.length()

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

**结论:**原理和数组一样,也是不影响

字符串的底层是Char[],length()也是返回这个数组的长度

public final class String {
    
    
    private final char value[];   //底层实现也是一个数组
    
    public int length() {
    
    
    return value.length;
   }

我们知道字符串是不可改变的,从上述源码我们也能推断出原因,因为value[]被final 修饰。与集合.size()相比,由于string中的value[]数组不可变,可以直接利用value.length作为返回值。

参考:
Java中for循环每次都通过list.size、str.length、length()获取数组或者字符串的长度是否消耗资源 感觉里面针对字符串说法是错误的。

java中三种长度方式及便利时是否消耗过多资源

猜你喜欢

转载自blog.csdn.net/m0_45406092/article/details/108597173