集合可以看做一种容器,即存储各种对象的容器,容器的实现方式有很多种(list,set),每种存储数据的方式(即数据结构)都有区别,但是它有很多共性的功能(增删改查等)。对集合的各种实现的共有方法进行抽取,可以得到一个金字塔形的集合框架,金字塔的最顶端就是Collection接口
Collection接口的子接口及实现类:
Collection接口源码(去掉注释后)
public interface Collection<E> extends Iterable<E> {
// Query Operations
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator iterator();
Object[] toArray();
T[] toArray(T[] a);
// Modification Operations
boolean add(E e);
boolean remove(Object o);
// Bulk Operations
boolean containsAll(Collection> c);
boolean addAll(Collection extends E> c);
boolean removeAll(Collection> c);
boolean retainAll(Collection> c);
void clear();
// Comparison and hashing
boolean equals(Object o);
int hashCode();
}
JavaSEAPI中对Collection接口部分方法的解析
boolean contains(Object o)
如果此 collection 包含指定的元素,则返回 true。
boolean containsAll(Collection < ? > c)
如果此 collection 包含指定 collection 中的所有元素,则返回 true。
boolean equals(Object o)
比较此 collection 与指定对象是否相等。
int hashCode()
返回此 collection 的哈希码值。
Iterator iterator()
返回在此 collection 的元素上进行迭代的迭代器。
因为java中的集合数据结构都直接或间接的继承或实现了Collection接口。所以Collection接口中定义有集合数据结构普遍有的增删查方法
Iterator被称作迭代器,是一个接口,通过迭代的方式取集合中的元素,java中所有的集合数据结构都可以通过迭代的方式取出集合中的元素,所以迭代器是所有数据结构的都有的功能,对这项功能进行向上抽取,定义了一个超级接口Iterator接口
Iterator接口的定义也很好的体现了面向对象的理念,定义一个迭代器类,并将用于对集合元素的迭代方法都封装起来定义到这个迭代器类中,当需要对集合中的元素进行迭代时只需要获取这个类的对象,让后调用对象中的方法即可
import java.util.Iterator;
public interface Iterable {
Iterator iterator();
}
Iterator接口源码(去掉注释)
public interface Iterator {
boolean hasNext();
E next();
void remove();
}
JavaSEAPI中对Iterator接口方法的解析
boolean hasNext()
如果仍有元素可以迭代,则返回 true。
E next()
返回迭代的下一个元素。
void remove()
从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。
定义iterator接口的原因:
每一个集合都有自己的数据结构,都有特定的取出自己内部元素的方式。为了便于操作所有的容器,取出元素。将容器内部的取出方式按照一个统一的规则向外提供,这个规则就是Iterator接口
也就说,只要通过该接口就可以取出Collection集合中的元素,至于每一个具体的容器依据自己的数据结构,如何实现的具体取出细节,则不去考虑,这样就降低了取出元素操作和不同数据结构集合的耦合
有序的 Collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,List列表允许重复的元素
List集合框架的特点:
1.有序(元素存入集合的顺序和取出的顺序一致)
2.元素都有索引
3.元素可以重复
List接口源码部分代码(去掉注释后)
package java.util;
public interface List<E> extends Collection<E> {
// Positional Access Operations
E get(int index);
E set(int index, E element);
void add(int index, E element);
E remove(int index);
// Search Operations
int indexOf(Object o);
int lastIndexOf(Object o);
// List Iterators
ListIterator listIterator();
ListIterator listIterator(int index);
// View
List subList(int fromIndex, int toIndex);
}
和Collection接口重复的一些方法没有列出,只列出了List接口特有的方法。可以看出,List接口对Collection的扩展方法中很多都是添加了用角标操作集合内的元素
List 接口的数组的实现,大小可变。实现了所有列表操作(增删查,比较等List接口中有的方法),并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法用来存储列表的数组的大小。
ArrayList类在功能上和Vector类非常相似,唯一不同的地方就是ArrayList类是不同步的,而Vector类则是同步的,Vector类已基本不用
ArrayList类的部分源码解析:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
----------------------------------1.ArrayList类中定义的变量及构造方法-----------------------------
//1.1 定义ArrayList的初始容量
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
//1.2 定义一个Object对象数组用来存储List集合的元素
private transient Object[] elementData;
//1.3 定义int类型的size属性,记录集合的大小
private int size;
//1.4 空参构造函数(还有带参的构造函数,这里不一一显示)
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
----------------------------------2.ArrayList类的特有方法,控制集合容量--------------------------------------
//用于在存入元素的过程中集合容量不够用时扩大集合容量
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);
}
-------------------------------------------3.ArrayList类的增删改查方法-----------------------------------------
//ArrayList添加元素的方法
public boolean add(E e) {
//调用方法检查容量是否足够
ensureCapacityInternal(size + 1); // Increments modCount!!
//List集合存储元素和角标信息一起存储
elementData[size++] = e;
return true;
}
//ArrayList的查询方法
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
//ArrayList检查是否包含元素
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
//ArrayList在指定角标地点添加元素
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
//ArrayList的更改元素方法
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
//ArrayList的删除方法
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
------------------------------------4.ArrayList类的增删改查方法的支持方法-------------------------------------------------
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
-------------------------------------------5.ArrayList类的迭代器------------------------------------
//5.1 返回一个实现了ListIterator接口的类的对象(一个迭代器对象),从指定的角标处开始迭代
public ListIterator listIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
//5.2 返回一个实现了ListIterator接口的类的对象(一个迭代器对象)
public ListIterator listIterator() {
return new ListItr(0);
}
//5.3 覆盖了AbstractList抽象类中iterator()方法,返回一个实现了Iterator接口的类的对象
public Iterator iterator() {
return new Itr();
}
//5.4 定义一个内部类,这个内部类实现了Iterator接口,根据数组列表的数据结构给出了迭代器的next,hasNext等方法的具体实现
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
//5.4.1 覆盖Iterator接口中的方法1:hasNext()
public boolean hasNext() {
return cursor != size;
}
//5.4.2 覆盖Iterator接口中的方法2:next()
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
//5.4.3 覆盖Iterator接口中的方法3:remove()
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
//5.5 定义一个内部类ListItr,继承了Itr类,实现了ListIterator接口,对Itr类进行了有关List集合的补充及扩展,如通过角标倒序(从后向前)迭代集合
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
ArrayList集合总结:
ArrayList实现数组数据结构的原因:
1.2 ArrayList定义一个Object对象数组用来存储List集合的元素,所以ArrayList集合对内部存储的元素的操作是对数组数据结构的操作,具有增删慢,查询快的特点
private transient Object[] elementData;
LinkedList类的部分源码解析:
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
-------------------------------------1.LinkedList类中定义的变量及构造方法----------------------------------
//集合的长度
transient int size = 0;
//集合的第一个元素
transient Node first;
//集合的最后一个元素
transient Node last;
//构造方法
public LinkedList() {
}
-----------------------------2.LinkedList类实现链表数据结构的重要部分,静态内部类,节点类-----------------------
//定义一个静态内部类--节点类,LinkedList将内部的每一个元素看做一个节点,即一个Node类的对象
private static class Node<E> {
E item;
//每个节点都包保存有它的前一个节点和后一个节点的信息
Node next;
Node prev;
//Node类的含参构造方法,共有3个参数,前一节点,元素对象,后一节点
Node(Node prev, E element, Node next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
-------------------------------------3.LinkedList类的增删改查方法----------------------------------------
//3.1 LinkedList在末尾添加元素
public boolean add(E e) {
linkLast(e);
return true;
}
//3.2 LinkedList在指定角标地点添加元素
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
//3.3 LinkedList删除指定元素
public boolean remove(Object o) {
if (o == null) {
for (Node x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
//3.4 LinkedList删除指定角标的元素
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
---------------------------4.LinkedList类的增删改查方法的支持方法(经过抽取得到的)-----------------------------
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
public E set(int index, E element) {
checkElementIndex(index);
Node x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
void linkLast(E e) {
final Node l = last;
final Node newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
void linkBefore(E e, Node succ) {
// assert succ != null;
final Node pred = succ.prev;
final Node newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
E unlink(Node x) {
// assert x != null;
final E element = x.item;
final Node next = x.next;
final Node prev = x.prev;
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
Node node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
---------------------------------5.LinkedList类的迭代器-------------------------------------------
//返回一个
public ListIterator listIterator(int index) {
checkPositionIndex(index);
return new ListItr(index);
}
private class ListItr implements ListIterator<E> {
private Node lastReturned = null;
private Node next;
private int nextIndex;
private int expectedModCount = modCount;
ListItr(int index) {
// assert isPositionIndex(index);
next = (index == size) ? null : node(index);
nextIndex = index;
}
public boolean hasNext() {
return nextIndex < size;
}
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}
public boolean hasPrevious() {
return nextIndex > 0;
}
public E previous() {
checkForComodification();
if (!hasPrevious())
throw new NoSuchElementException();
lastReturned = next = (next == null) ? last : next.prev;
nextIndex--;
return lastReturned.item;
}
public int nextIndex() {
return nextIndex;
}
public int previousIndex() {
return nextIndex - 1;
}
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
Node lastNext = lastReturned.next;
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}
public void set(E e) {
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.item = e;
}
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}