JAVA集合一 ——集合整体接口
特别声明:
*本文只是备忘录。
JAVA中集合是一个很重要的概念,首先来看看整体的类图。
集合的主要接口为collection。Collection 继承自Iterable接口,而Iterable接口封装了生成迭代器的方法Iterator()。这样所有集合都需要实现该方法,这也是java设计模式中的迭代器模式。
由图中可以看出集合的几个主要的子接口为:List、Set、Queue。一个抽象实现类 AbstractCollection。
List、Set、Queue接口后面分析。先来看AbstractCollection。
AbstractCollection 主要是提供了一些Collection接口的方法的实现。
主要看一下 toArray()方法。
public Object[] toArray() {
// Estimate size of array; be prepared to see more or fewer elements
Object[] r = new Object[size()];
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) // fewer elements than expected
return Arrays.copyOf(r, i);
r[i] = it.next();
}
return it.hasNext() ? finishToArray(r, it) : r;
}
将集合中的元素复制到数组中。看看最后返回的是什么?最后为什么还要判断it.hasNext()?
能产生这种问题的情况,多线程!。
在来看看 finishToArray()的源码:
private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
int i = r.length;
while (it.hasNext()) {
int cap = r.length;
if (i == cap) {
int newCap = cap + (cap >> 1) + 1;
// overflow-conscious code
if (newCap - MAX_ARRAY_SIZE > 0)
newCap = hugeCapacity(cap + 1);
r = Arrays.copyOf(r, newCap);
}
r[i++] = (T)it.next();
}
// trim if overallocated
return (i == r.length) ? r : Arrays.copyOf(r, i);
}
int newCap = cap + (cap >> 1) + 1;
if (newCap - MAX_ARRAY_SIZE > 0)
newCap = hugeCapacity(cap + 1);
private static int hugeCapacity(int minCapacity) {
//该处判断上面的cap + 1是否已经超出了int的最大值。
if (minCapacity < 0) // overflow
throw new OutOfMemoryError
("Required array size too large");
//判断扩容后的值是否大于数组的最大size,如果大于返回INT的最大值。否则返回定义的最大值
return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE :MAX_ARRAY_SIZE;
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
再来看看List、Set、Queue接口。
List:定义的是有序的集合,允许元素的重复。允许多个null。
Set:定义的是不能重复的集合,可以有null,但是只能有一个。Set分有序和无需的。TreeSet:有序,hashSet:无需。
Queue: 定义的是"队列"先进先出(FIFO)的数据结构。不允许随机访问。
后面会具体分析。