手记

JAVA优化建议(6)

1.在明确的场景下,为集合指定初始容量
因为在使用add、remove方法操作的话,都需要扩容
以ArrayList为例
如果是有add方法,源码如下:

 public boolean add(E e) {
 ensureCapacityInternal(size + 1);  // Increments modCount!!
 elementData[size++] = e;
 return true;
}

 private void ensureCapacityInternal(int minCapacity) {
 if (elementData == EMPTY_ELEMENTDATA) {
     minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
 }

 ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    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);
}


每执行一个add会扩一次容
如果固定长度,例如固定长度为15在15范围之内就不扩容,

 public ArrayList(int initialCapacity) {
 super();
 if (initialCapacity < 0)
     throw new IllegalArgumentException("Illegal Capacity: "+
                                        initialCapacity);
 this.elementData = new Object[initialCapacity];
}

//如果不初始化
public ArrayList() {
      super();
      this.elementData = EMPTY_ELEMENTDATA;
  }
private static final Object[] EMPTY_ELEMENTDATA = {};

2.基本数据类型作为asList的输入参数,导致不必要的逻辑错误
因为asList传入的参数是变长参数泛型,基本类型不能转化为泛型,但是数组可以

public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

所以会出现如下的现象

int[] data = {1,2,3,4,5};
List list = Arrays.asList(data);
System.out.println("list 的 容量:"+list.size());
System.out.println(data.equals(list.get(0)));

打印结果如下:
list 的 容量:1
true
asLsit把数组整体放入list(0)中了
但是引用类型不会出现

Integer[] data1 = {1,2,3,4,5};
List list1 = Arrays.asList(data1);
System.out.println("list1 的 容量:"+list1.size());
System.out.println(data1.equals(list1.get(0)));

打印结果如下:
list1 的 容量:5
false

3.asArrayList产生的对象List不可更改

Integer[] data1 = {1,2,3,4,5};
List list1 = Arrays.asList(data1);
list1.add(6);

则会报错
Exception in thread “main” java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at Main.main(Main.java:49)
原因是:

public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

这里的ArrayList不是java.util.ArrayList
而是他的内部类

private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
 {
     private static final long serialVersionUID = -2764017481108945198L;
     private final E[] a;

     ArrayList(E[] array) {
         if (array==null)
             throw new NullPointerException();
         a = array;
     }

父类的add方法

public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

4.可以随机存取的用for(int i=0;i<list.size();i++)例如ArrayList
不可以随机存取的用for(int i:list) 例如LinkedList

0人推荐
随时随地看视频
慕课网APP