Java容器类
java容器类图
interface Iterable
官方介绍
- 实现这个接口允许对象成为“for-each循环”语句的目标
方法
-
iterator()
- 返回一个迭代器
-
forEach(Consumer<? super T> action)
- 默认的forEach方法
-
spliterator()
interface Collection extends Iterable
介绍
- Java集合类的根接口
方法
interface Queue extends Collection
介绍
- 用于在处理之前保存元素的集合。除了基本的Collection操作外,队列还提供额外的插入、提取和检查操作。这些方法都以两种形式存在:一种方法在操作失败时抛出异常,另一种方法返回特殊值(null或false,取决于操作)。插入操作的后一种形式专门设计用于容量受限的队列实现;在大多数实现中,插入操作不会失败。
interface List extends Collection
abstract class AbstractCollection implements Collection
方法
- toArray()
public Object[] toArray() {
// Estimate size of array; be prepared to see more or fewer elements
Object[] r = new Object[size()]; //获取size初始化Object数组
Iterator<E> it = iterator();//获取迭代器
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) // 如果比期望中的元素要更少,i则为数组真实长度使用Arrays.copyOf(r, i)复制r并返回
return Arrays.copyOf(r, i);
r[i] = it.next();//填充数组r
}
return it.hasNext() ? finishToArray(r, it) : r;//判断it是否还有 ? 继续遍历 : 返回r
}
private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
int i = r.length; //获取r长度
while (it.hasNext()) { //遍历迭代器
int cap = r.length; //获取r长度
if (i == cap) { //如果i = cap 说明r已被填充满,需要扩容
int newCap = cap + (cap >> 1) + 1; //newCap = cap + cap/2 +1
// overflow-conscious code
if (newCap - MAX_ARRAY_SIZE > 0) //判断新的size是否超出最大size
newCap = hugeCapacity(cap + 1); //超出使用大容量size 方法
r = Arrays.copyOf(r, newCap); //复制r并扩容size为newCap
}
r[i++] = (T)it.next(); //填充r 并将index加1
}
// trim if overallocated
return (i == r.length) ? r : Arrays.copyOf(r, i); //若有,修剪多余的长度
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) //cap + 1 超出整数最大值变为负数
throw new OutOfMemoryError
("Required array size too large");
return (minCapacity > MAX_ARRAY_SIZE) ? // 大于数组最大size吗 ? 赋值整数最大值 : 赋值数组最大值
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
public <T> T[] toArray(T[] a) {
// Estimate size of array; be prepared to see more or fewer elements
int size = size();
T[] r = a.length >= size ? a :
(T[])java.lang.reflect.Array
.newInstance(a.getClass().getComponentType(), size); //初始化数组 长度为两者中最长的
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) { // fewer elements than expected
if (a == r) {
r[i] = null; // null-terminate
} else if (a.length < i) {
return Arrays.copyOf(r, i);
} else {
System.arraycopy(r, 0, a, 0, i);
if (a.length > i) {
a[i] = null;
}
}
return a;
}
r[i] = (T)it.next();
}
// more elements than expected
return it.hasNext() ? finishToArray(r, it) : r;
}
由于AbstractCollection大部分方法很直白,且被子类覆盖,不再多做介绍。
abstract class AbstractList extends AbstractCollection implements List
介绍
- 该类提供List接口的框架实现,以最小化由“随机访问”数据存储(例如数组)支持的实现该接口所需的工作。对于顺序访问数据(例如链表),应该优先使用AbstractSequentialList而不是该类。
- 要实现一个不可修改的列表,程序员只需扩展这个类并为get(int)和size()方法提供实现。
- 要实现一个可修改的列表,程序员必须另外覆盖set(int, E)方法(否则会抛出一个UnsupportedOperationException)。如果列表是可变大小的,程序员必须另外覆盖add(int, E)和remove(int)方法。
- 按照集合接口规范中的建议,程序员通常应该提供一个void(无参数)和集合构造函数。
- 与其他抽象集合实现不同,程序员不必提供迭代器实现;迭代器和列表迭代器是由这个类实现的,在“随机访问”方法之上:get(int)、set(int, E)、add(int, E)和remove(int)。
- 该类中每个非抽象方法的文档详细描述了其实现。如果正在实现的集合允许更有效的实现,则可能会覆盖这些方法。
- 该类是Java集合框架的成员。
大部分方法都很直白,不表,主要注意迭代器实现、SubList有单独的实现为啥还要在 AbstractList写了一个内部实现。同理,RandomAccessSubList亦是。
class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable
介绍
-
List接口的可调整大小的数组实现。实现所有可选的 List操作,并允许所有元素,包括null。除了实现List接口之外,该类还提供了一些方法来操作内部用于存储List的数组的大小,(这个类大致相当于Vector,只是它是不同步的。)
-
size、isEmpty、get、set、iterator和listIterator操作在常数时间内运行。添加操作在平摊常数时间内运行,也就是说,添加n个元素需要O(n)个时间。所有其他操作都在线性时间内运行(粗略地说)。与LinkedList实现相比,常量因子较低。
-
每个ArrayList实例都有一个容量。容量是用于存储列表中的元素的数组的大小。它总是至少与列表大小一样大。当元素被添加到ArrayList中时,它的容量会自动增长。增长策略的细节没有指定,除了添加一个元素有恒定的平摊时间成本。
-
在使用ensureCapacity操作添加大量元素之前,应用程序可以增加ArrayList实例的容量。这可能会减少增量重新分配的数量。
-
注意,这个实现不是同步的。如果多个线程同时访问一个ArrayList实例,并且至少有一个线程从结构上修改了这个列表,那么它必须在外部进行同步。(结构修改是指增加或删除一个或多个元素,或显式调整背景阵列的大小的任何操作;仅仅设置元素的值并不是一种结构修改。)这通常是通过对一些自然封装列表的对象进行同步来实现的。如果不存在这样的对象,则应该使用Collections.synchronizedList 方法对List进行“包装”。synchronizedList方法。这最好在创建时完成,以防止意外的不同步访问列表,如下:
List list = Collections.synchronizedList(new ArrayList(...));
-
这个类的iterator和listIterator方法返回的迭代器是快速失效的:如果在创建迭代器之后的任何时候,以任何方式(除了通过迭代器自己的删除或添加方法)对列表进行结构修改,迭代器将抛出ConcurrentModificationException异常。因此,在面对并发修改时,迭代器会快速而干净地失败,而不是在将来某个不确定的时间冒任意的、不确定的行为的风险。
-
注意,不能保证迭代器的快速故障行为,因为通常来说,在存在非同步并发修改的情况下,不可能做出任何严格的保证。故障快速迭代器在最大努力的基础上抛出ConcurrentModificationException。因此,编写一个依赖于这个异常的正确性的程序是错误的:迭代器的快速故障行为应该只用于检测bug。
-
该类是Java集合框架的成员。