集合 -- Collection<E>
集合的父接口--用于定义存储多种数据类型的集合。
集合中存储何种数据使用泛型进行限定。
主要定义的方法:
boolean | add(E e) 添加数据到集合中 |
boolean | addAll(Collection<? extends E> c) 将指定 collection 中的所有元素都添加到此 collection 中 |
void | clear() 移除此 collection 中的所有元素 |
boolean | contains(Object o) 如果此 collection 包含指定的元素,则返回 true。 |
boolean | containsAll(Collection<?> c) 如果此 collection 包含指定 collection 中的所有元素,则返回 true。 |
boolean | equals(Object o) 比较此 collection 与指定对象是否相等。 |
int | hashCode() 返回此 collection 的哈希码值。 |
boolean | isEmpty() 如果此 collection 不包含元素,则返回 true。 |
Iterator<E> | iterator() 返回在此 collection 的元素上进行迭代的迭代器。 |
boolean | remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话 |
boolean | removeAll(Collection<?> c) 移除此 collection 中那些也包含在指定 collection 中的所有元素。 |
boolean | retainAll(Collection<?> c) 仅保留此 collection 中那些也包含在指定 collection 的元素 |
int | size() 返回此 collection 中的元素数。 |
Object[] | toArray() 返回包含此 collection 中所有元素的数组。 |
<T> T[] | toArray(T[] a) 返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。 |
List(有序列表)
List接口继承了Collection,是有序的集合 (保证元素的存入顺序)--存在对应的下标,因此能够通过下标来操作列表中的元素
除了继承Collection的方法外,还额外增加了:
方法摘要 |
|
void | add(int index, E element) 在列表的指定位置插入指定元素(可选操作)。 |
boolean | addAll(int index, Collection<? extends E> c) 将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。 |
boolean | contains(Object o) 如果列表包含指定的元素,则返回 true。 |
boolean | containsAll(Collection<?> c) 如果列表包含指定 collection 的所有元素,则返回 true。 |
boolean | equals(Object o) 比较指定的对象与列表是否相等。 |
E | get(int index) 返回列表中指定位置的元素。 |
int | indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。 |
Iterator<E> | iterator() 返回按适当顺序在列表的元素上进行迭代的迭代器。 |
int | lastIndexOf(Object o) 返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。 |
ListIterator<E> | listIterator() 返回此列表元素的列表迭代器(按适当顺序)。 |
ListIterator<E> | listIterator(int index) 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。 |
E | remove(int index) 移除列表中指定位置的元素(可选操作)。 |
boolean | remove(Object o) 从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。 |
boolean | retainAll(Collection<?> c) 仅在列表中保留指定 collection 中所包含的元素(可选操作)。 |
E | set(int index, E element) 用指定元素替换列表中指定位置的元素(可选操作)。 |
List<E> | subList(int fromIndex, int toIndex) 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。 |
Object[] | toArray() 返回按适当顺序包含列表中的所有元素的数组(从第一个元素到最后一个元素)。 |
<T> T[] | toArray(T[] a) 返回按适当顺序(从第一个元素到最后一个元素)包含列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。 |
List的主要实现类:
ArrayList:
基于数组的实现,实现了所有可选的列表操作,并允许包括null在内的所有元素。默认的存储容量是10,在内存中空间是连续的
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
ArrayList的扩容:
每次扩容是在原来基础上增加一半,右移进行增加。
主要源码:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//进行原来容量+原容量/2的扩容
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);
}
LinkedList:
基于node节点进行存储,将节点连成链表,底层是基于指针进行连接,所以空间不连续。查找复杂,增删只需要调度指针,所以简单。(是一个双向链表)
node源码:
private static class Node<E> {
//存储元素
E item;
//后继节点
Node<E> next;
//前驱节点
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
获取指定位置上的节点:
Node<E> node(int index) {
//判断下标是否小于整个列表总数的一半
if (index < (size >> 1)) {
//进行头结点往后遍历查找
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
//进行尾节点后续遍历查找
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
采用了撇半寻找策略:减少了一半的寻找。
考虑:如果在增删和查询的次数相差不多的情况下,使用ArrayList还是LinkedList? --- LinkedList(可以利用零散内存)
Vector:
基于数组,内存空间连续,默认容量为10,默认每次增加当前容量的一倍。区别于上面2个List集合是线程安全的集合,线程不安全方法都使用了Synchronized关键字加锁。
扩容源码:capacitylncrement初始化可以指定。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//根据容量增量是否>0(默认是0),进行扩容原本容量大小,还是增量大小
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
完整初始化构造方法:
//初始化容量和扩容增量
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
Stack:栈。继承Vector。遵循先进后出的原则。
主要方法:push(压栈),pop(出栈),peek(查看栈顶元素)