复制一个List集合:
public class Test2{
public static void main(String[] args){
List list = new ArrayList() ;
list.add(3) ;
list.add(6) ;
list.add(1) ;
list.add(2) ;
list.add(100) ;
list.add(5) ;
List list2 = new ArrayList(list.size()) ;
list2.addAll(list) ;
System.out.println("===========>");
System.out.println("原List"+list);
System.out.println("复制List"+list2);
List list3 = new ArrayList(list.size()) ;
Collections.copy(list3,list);
System.out.println("复制的list"+list3);
}
}
总结:复制一个list,可以用“目标list.addAll(要复制的list)” ;
使用Collections.copy(目标list,原list) ;会有数组下标越界报错。
list集合排序:
public class Test3 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>() ;
list.add(3) ;
list.add(6) ;
list.add(1) ;
list.add(2) ;
list.add(100) ;
list.add(5) ;
Collections.sort(list);
System.out.println(" Collections.sort从小到大排序结果"+list);
Collections.reverse(list);
System.out.println(" Collections.sort从大到小排序结果"+list);
list.sort(Comparator.naturalOrder());
System.out.println(" list.sort从小到大排序结果"+list);
list.sort(Comparator.reverseOrder());
System.out.println(" list.sort从大到小排序结果"+list);
}
}
ArrayList的扩容机制:
概述:ArrayList是List接口的实现,它是支持根据需要而动态增长的数组。java中标准数组是定长的,在数组被创建之后,他们不能被加长或者缩短。这就意味着在创建数组时需要知道数组的所需长度,但有时我们需要动态程序中获取数组长度。ArrayList就是为此而生的。
ArrayList的扩容机制
扩容发生在add()方法调用的时候。
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
说明:代码中ensureCapacityInternal()方法是用来扩容的,传入的形式参数为“最小扩容量”
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
【扩容核心方法】
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
//===1获取ArrayList中元素数据的内存长度。确定它当前的容量大小
int oldCapacity = elementData.length;
//===2扩容为当前容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
//===3判断扩容后的数组的容量够不够,如果够了就直接使用这个长度创建数组,如果不够就将数组长度设置为需要的长度。
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//===4如果预设的数组容量值大于默认的最大值
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
//调用Arrays.copyOf()方法将elementData数组指向新的内存空间是newCapacity的连续空间。并且将elementData数据元素复制给新数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
说明:
(1)在calculateCapacity()方法中,如果传入的是一个空数组则最小容量取默认容量与minCapatity参数之间的最大值。”
(2)而ensureExplicitCapacity()方法,用来判断是否需要扩容,该方法中如果最小需要空间比elementData的内存空间大,则需要扩容
(3)grow()方法是扩容的核心方法
ArrayList扩容的本质:就算出新的扩容数组的size后实例化,并将原有数组内容复制到新数组中去。
总之,再通俗一点ArrayList的默认容量是10,如果初始化的时候就指定了容量或者放入了一个指定的集合参数,那么容量的大小就是这个指定的大小或者是放入的这个集合的size。每次扩容为原来的1.5倍。如果新增后超过这个容量,则容量为新增后所需的最小容量。如果增加0.5倍后的新容量超过限制的容量,则用所需的最小容量与限制的容量进行判断,超过则指定为Integer的最大值,否则指定为限制容量大小。然后通过数组的复制将原数据复制到一个更大(新的容量大小)的数组。