Java中常见的集合类主要有List、Set和Map。这些集合类使用广泛,因此深入了解它们的实现原理非常重要。在Java的集合类中,最常用的是ArrayList、LinkedList、HashSet和HashMap,这些集合类的实现基本都依赖于数组和链表。
一、ArrayList源码
ArrayList是Java中最常用的集合类之一,它底层使用数组实现,它的查询效率比LinkedList高。在ArrayList中,随机访问元素的时间复杂度为O(1),增加或删除元素的时间复杂度为O(n)。
在Java 8版本中,ArrayList的源码中有一些新的方法,比如spliterator(),用于提供集合的可分割性和遍历性。另外,还有sort()和replaceAll()方法,用于对集合进行排序和替换元素。
下面是ArrayList的部分源代码,用于展示ArrayList的实现原理。
代码语言:javascript复制public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
/**
* 默认的初始化数组容量大小
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 元素实际数量
*/
private int size;
/**
* 存放元素的数组
*/
private Object[] elementData;
/**
* ArrayList默认构造函数
*/
public ArrayList() {
this.elementData = new Object[DEFAULT_CAPACITY];
}
/**
* ArrayList带初始化大小的构造函数
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = new Object[]{};
} else {
throw new IllegalArgumentException("Illegal Capacity: "
initialCapacity);
}
}
/**
* 向ArrayList末尾添加元素
*/
public boolean add(E e) {
ensureCapacityInternal(size 1); // Increments modCount!!
elementData[size ] = e;
return true;
}
/**
* 返回ArrayList指定下标的元素
*/
@SuppressWarnings("unchecked")
public E get(int index) {
rangeCheck(index);
return (E) elementData[index];
}
/**
* 确保ArrayList容量足够
*/
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
/**
* 确保ArrayList容量足够
*/
private void ensureExplicitCapacity(int minCapacity) {
modCount ;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 扩容ArrayList大小
*/
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
* ArrayList迭代器
*/
public Iterator<E> iterator() {
return new Itr();
}
/**
* 内部类Itr,ArrayList的迭代器实现
*/
private class Itr implements Iterator<E> {
//...
}
//...
}
二、LinkedList源码
LinkedList是Java中另一个常用的集合类,它底层使用双向链表实现。在LinkedList中,插入和删除元素的时间复杂度为O(1),获取元素的时间复杂度为O(n)。
与ArrayList不同,LinkedList还支持栈和队列操作,比如poll()、offer()和push()等方法,这些方法可以实现在集合的开头和结尾插入、删除元素。
下面是LinkedList的部分源代码,用于展示LinkedList的实现原理。
代码语言:javascript复制public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable {
/**
* 链表长度
*/
transient int size = 0;
/**
* 链表头部
*/
transient Node<E> first;
/**
* 链表尾部
*/
transient Node<E> last;
/**
* 构造一个空链表
*/
public LinkedList() {
}
/**
* 向链表头部插入元素
*/
private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size ;
modCount ;
}
/**
* 链表中删除指定元素
*/
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
/**
* 链表从头向尾遍历元素
*/
public Iterator<E> iterator() {
return new ListItr(0);
}
/**
* 内部类ListItr,链表迭代器的实现
*/
private class ListItr implements ListIterator<E> {
//...
}
/**
* 内部类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;
}
}
}
三、HashSet源码
HashSet是Java中常用的Set集合类,它底层使用HashMap来实现。在HashSet中,元素的添加、删除和查找操作时间复杂度均为O(1)。
HashSet与HashMap实现的主要区别是,在HashSet中,添加元素是将元素添加到HashMap的key值上,value值是一个FINAL new object();
下面是HashSet的部分源代码,用于展示HashSet的实现原理。
代码语言:javascript复制public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
/**
* 底层使用的HashMap实例
*/
private transient HashMap<E,Object> map;
/**
* 集合元素的默认值
*/
private static final Object PRESENT = new Object();
/**
* 构造一个空HashSet
*/
public HashSet() {
map = new HashMap<>();
}
/**
* 向HashSet中添加元素
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
/**
* 返回集合的迭代器
*/
public Iterator<E> iterator() {
return map.keySet().iterator();
}
//...
}