zoukankan      html  css  js  c++  java
  • java中ArrayList 遍历方式、默认容量、扩容机制

     

    遍历

    先定义ArrayList,并填充数据

                    //定义集合
            ArrayList arr = new ArrayList<>();
            //添加数据
            for(int i = 0; i < 10; i ++) {
                arr.add(i);
            }        

    1、下标遍历

    for (int i = 0; i < arr.size(); i++) {
        System.out.println(arr.get(i));
    }

    2、foreEach (jdk 1.5 及以上可用)

    for (int i = 0; i < arr.size(); i++) {
        System.out.println(arr.get(i));
    }

    3、java 8 新特性 Lambda表达式 (jdk 1.8 及其以上)

    arr.forEach(x -> System.out.println(x));

    4、Iteraotr迭代器

    Iterator iterator = arr.iterator();
    while(iterator.hasNext()) {
        System.out.println(iterator.next());
    }

    5、ListIterator 迭代器 (这个是List集合特有的)

    //List转用迭代
    ListIterator listIterator = arr.listIterator();
    //从前往后
    System.out.println("listIterator 从前往后 ");
    while(listIterator.hasNext()) {
        System.out.println(listIterator.next());
    }
    
    //从后往前
    System.out.println("listIterator 从后往前 ");
    while(listIterator.hasPrevious()) {
        System.out.println(listIterator.previous());
    }

    默认容量,和扩容机制

    默认容量为10,有图有真相:

    扩容机制,先看一下扩容的源代码吧:

        //minCapacity 代表着最小扩容量
        private void grow(int minCapacity) {
            // overflow-conscious code
            //elementData 是 ArrayList存储数据的数组 这里是获取当前数组的长度
            int oldCapacity = elementData.length;
            //计算扩容后的数组长度 = 当前数组长度  + (当前数组长度 * 0.5) ;也就是扩容到当前的 1.5 倍
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            //判断新的数组是否满足最小扩容量,如果不满足就将新数组的扩容长度赋值为最小扩容量
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
        }

    恩,也就是说ArrayList通常的套路是当容量不足时就扩容到当前容量的 1.5被。下面我通过java反射机制证明这一点:

    public static void main(String[] args) throws Exception {
            ArrayList a = new ArrayList<>();
            for (int i = 0; i < 30; i++) {
                a.add(i);
                print(a);
            }
        }
        static void print(List list) throws Exception {
            Class c = list.getClass();
            //elementData 就是ArrayList用于底层存储数据的数组,
            //我们通过观察数组长度的变化来证明我们所说的扩容机制正确性
            Field  f = c.getDeclaredField("elementData");
            //设置可访问
            f.setAccessible(true);
            //反射对象
            Object[] elementData = (Object[])f.get(list);
            System.out.println("elementData.length" + elementData.length + ",size" + list.size());
        }

    下面时执行结果:

    elementData.length10,size1
    elementData.length10,size2
    elementData.length10,size3
    elementData.length10,size4
    elementData.length10,size5
    elementData.length10,size6
    elementData.length10,size7
    elementData.length10,size8
    elementData.length10,size9
    elementData.length10,size10
    elementData.length15,size11
    elementData.length15,size12
    elementData.length15,size13
    elementData.length15,size14
    elementData.length15,size15
    elementData.length22,size16
    elementData.length22,size17
    elementData.length22,size18
    elementData.length22,size19
    elementData.length22,size20
    elementData.length22,size21
    elementData.length22,size22
    elementData.length33,size23
    elementData.length33,size24
    elementData.length33,size25
    elementData.length33,size26
    elementData.length33,size27
    elementData.length33,size28
    elementData.length33,size29
    elementData.length33,size30

    ArrayList扩容是向上取整还是向下取整?

    int newCapacity = oldCapacity + (oldCapacity >> 1);

    oldCapacity >> 1 就是 oldCapacity * 0.5 jdk人员将它设计成这样是为了更高的效率。记住  oldCapacity >> 1 是向下取整 。

     

  • 相关阅读:
    【Python基础编程196 ● 文件/文件夹操作 ● 文件的操作步骤】
    【Python基础编程197 ● 文件/文件夹操作 ● 文件的访问模式】
    【Python基础编程199 ● 文件/文件夹操作 ● Python怎么读/写很大的文件】
    【Python基础编程198 ● 文件/文件夹操作 ● 读取文件的4种方式】
    【等待优化】如何定位网络性能问题 ASYNC_NETWORK_IO 等待
    (4.48)sql server添加列并使用默认值填充已有记录
    【sql server安全】sql server列加密查询性能问题及解决方案
    【sql server安全】sql server使用混合密钥实现列加密
    【sql server安全】sql server使用非对称秘钥实现列加密
    【sql server安全】sql server使用对称秘钥实现列加密
  • 原文地址:https://www.cnblogs.com/IT-CPC/p/10886007.html
Copyright © 2011-2022 走看看