Java数据结构(2)ArrayList

2018-03-09  本文已影响0人  jia33

ArrayList

ArrayList的使用优化

  1. 上面说到的动态数组,就存在扩容的问题
    public void add(int index, E element) {
        if (index > size || index < 0)
             throw new IndexOutOfBoundsException(
             "Index: "+index+", Size: "+size);

         ensureCapacity(size+1);  // Increments modCount!!
         System.arraycopy(elementData, index, elementData, index + 1,
             size - index);
         elementData[index] = element;
         size++;
     }

看看ensureCapacity():

     public void ensureCapacity(int minCapacity) {
         // 将“修改统计数”+1
         modCount++;
         int oldCapacity = elementData.length;
         // 若当前容量不足以容纳当前的元素个数,设置 新的容量=“(原始容量x3)/2 + 1”
             Object oldData[] = elementData;
              int newCapacity = (oldCapacity * 3)/2 + 1;
              if (newCapacity < minCapacity)
                  newCapacity = minCapacity;
              elementData = Arrays.copyOf(elementData, newCapacity);
          }
      }

当然不同jdk版本写法略有不同,上面是1.6版本的,1.8版本的如下:

    private void grow(int minCapacity) {
        ...
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        // 结果都是一样的
        ...
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
  1. 使用优化:
    由于初始化ArrayList,默认数组长度是10,如果是特别大的数据,可通过ensureCapacity(int length)初始化数组长度;
public static void main(String[] args){
        final int N = 10000000;
        Object obj = new Object();
        
        //没用调用ensureCapacity()方法初始化ArrayList对象
        ArrayList list = new ArrayList();
        long startTime = System.currentTimeMillis();
        for(int i=0;i<=N;i++){
            list.add(obj);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("没有调用ensureCapacity()方法所用时间:" + (endTime - startTime) + "ms");
        
        //调用ensureCapacity()方法初始化ArrayList对象
        list = new ArrayList();
        startTime = System.currentTimeMillis();
        list.ensureCapacity(N);//预先设置list的大小
        for(int i=0;i<=N;i++){
            list.add(obj);
        }
        endTime = System.currentTimeMillis();
        System.out.println("调用ensureCapacity()方法所用时间:" + (endTime - startTime) + "ms");
    }

运行结果:
没有调用ensureCapacity()方法所用时间:137ms
调用ensureCapacity()方法所用时间:78ms

补充一点:arraycopy本地方法是通过c的动态内存分配,创建动态数组,这点java没法做到
System.arraycopy(a, 0, newArray, 0, s);

public static native void arraycopy(Object src, int srcPos,Object dst, int dstPos, int length);

上一篇 下一篇

猜你喜欢

热点阅读