以下,结合源码分析集合类所有集合数据结构对接口。以JDK1.8为准。
1. Collection
int size()
//返回此 collection 中的元素数。
//如果此 collection 包含的元素大于 Integer.MAX_VALUE,则返回 Integer.MAX_VALUE。
boolean isEmpty()
//如果此 collection 不包含元素,则返回 true。
boolean contains(Object o)
//当且仅当此 collection 至少包含一个满足 (o==null ? e==null : o.equals(e)) 的元素 e 时,返回 true。
Iterator<E> iterator()
//返回在此 collection 的元素上进行迭代的迭代器。
//关于元素返回的顺序没有任何保证,除非此 collection 是某个能提供保证顺序的类实例。
Object[] toArray()
//返回包含此 collection 中所有元素的数组。
//如果 collection 对其迭代器返回的元素顺序做出了某些保证,那么此方法必须以相同的顺序返回这些元素。
//返回的数组将是“安全的”,因为此 collection 并不维护对返回数组的任何引用。
//调用者可以随意修改返回的数组。
//此方法充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。
boolean add(E e)
//确保此 collection 包含指定的元素。如果此 collection 由于调用而发生更改,则返回 true。
//如果此 collection 不允许有重复元素,并且已经包含了指定的元素,则返回 false。
boolean remove(Object o)
//如果此 collection 包含一个或多个满足 (o==null ? e==null : o.equals(e)) 的元素 e,则移除这样的元素。
//如果此 collection 包含指定的元素(或者此 collection 由于调用而发生更改),则返回 true 。
boolean containsAll(Collection<?> c)
//如果此 collection 包含指定 collection 中的所有元素,则返回 true。
boolean addAll(Collection<? extends E> c)
//将指定 collection 中的所有元素都添加到此 collection 中。
//如果在进行此操作的同时修改指定的 collection,那么此操作行为是不确定的。
boolean removeAll(Collection<?> c)
//移除此 collection 中那些也包含在指定 collection 中的所有元素。
//此调用返回后,collection 中将不包含任何与指定 collection 相同的元素。
void clear()
//移除此 collection 中的所有元素。
boolean retainAll(Collection<?> c)
//仅保留此 collection 中那些也包含在指定 collection 的元素。
//移除此 collection 中未包含在指定 collection 中的所有元素。
collection作为接口拥有以上这些待实现的方法,除此之外,还有一个default方法和几个为了配合stream的方法,只有在1.8的jdk中可见。接口中已经实现的方法是removeIf,参数为Predicate类的过滤器。
2. Iterator
Iterator<Integer> it = new Iterator<>();
Iterator<Integer> it = queue.iterator();
Iterator类很简单,只有三个方法,next、hasnext、remove。和一个已经被实现的方法forEachRemaining,接受一个Consumer类对象,意思是对剩余未迭代对象进行消费。
注意位置!Iterator的位置在对象和对象之间,起始位置是第一个对象前。这种情况造成了很多限制,不能连续remove、开始不能直接remove。
为什么有这些限制呢?因为Iterator代码实现的时候,设置了两个变量,一个负责记录下一个位置的索引,另一个负责记录刚才走过位置的索引,如果刚才的位置被删除或者刚开始时,第二个参数的值都是-1,不能继续进行remove。下面贴上一些相关代码。
int cursor = 0;
int lastRet = -1;
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size();
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
3. List
List作为直接继承Collection的接口,方法差不多,其中实现了sort方法,怕在List类型下直接被Stream调用sort,这个方法的实现很有必要。
除此之外,
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
List中实现了replaceAll的方法,这个方法接收一个UnaryOperator接口实例,这个接口就是简化版Function接口,参数和输出要保持一直的意思,这里贴一下UnaryOperator的源代码。
public interface UnaryOperator<T> extends Function<T, T> {
/**
* Returns a unary operator that always returns its input argument.
*
* @param <T> the type of the input and output of the operator
* @return a unary operator that always returns its input argument
*/
static <T> UnaryOperator<T> identity() {
return t -> t;
}
}
虽然UnaryOperator比较大的卖点在于identity,但是估计List的意思是还是看中了它本身的意思,一元运算符。允许对所有元素做替换。
除此之外,List类中还有ListIterator实例,既然有实例,那就也要有调用的方法。ListIterator<E> listIterator(); ListIterator<E> listIterator(int index);
4. ListIterator
ListIterator继承了Iterator接口,专门为List设计,在原来的方法的基础上增加了向前看,查前/后索引的功能。而且可以进行值的设置。
5. AbstractCollection
从这个方法开始将会慢慢实现上面“挖的坑”,将会逐渐实现部分方法。但是AbstractCollection中实现的基本都是通用方法,类似clear,addAll这类即使具体的数据结构不同也不会有差别的方法。
6. AbstractList
这个类中实现了Itrator的所有方法,具体的数据结构和变量方法就像Iterator中描述的那样。
7. Set
什么都没做,照搬了所有Collection的方法。
8.Queue
Queue不算是数据结构中比较主流的一个结构,因为队列的操作可以被list模仿,但是java还是为Queue提供了一套全新的方法
boolean add(E e);
boolean offer(E e);
E remove();
E poll();
E element();
E peek();
9. AbstractSet
一共三个实现方法,equals、hashCode、removeAll。
public int hashCode() {
int h = 0;
Iterator<E> i = iterator();
while (i.hasNext()) {
E obj = i.next();
if (obj != null)
h += obj.hashCode();
}
return h;
}
其中hashcode的实现比较有意思,AbstractSet实现类对象的hashcode值是其中的每个对象的hashcode值加起来之和。
10. SortSet
SortSet是比较关键的一个接口,这个接口提供了为Set排序的概念,TreeSet就是继承这个接口。
public interface SortedSet<E> extends Set<E> {
Comparator<? super E> comparator();
SortedSet<E> subSet(E fromElement, E toElement);
SortedSet<E> headSet(E toElement);
SortedSet<E> tailSet(E fromElement);
E first();
E last();
11. AbstractSequentialList
public E get(int index) {
try {
return listIterator(index).next();
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
public E set(int index, E element) {
try {
ListIterator<E> e = listIterator(index);
E oldVal = e.next();
e.set(element);
return oldVal;
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
public void add(int index, E element) {
try {
listIterator(index).add(element);
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
public E remove(int index) {
try {
ListIterator<E> e = listIterator(index);
E outCast = e.next();
e.remove();
return outCast;
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
public boolean addAll(int index, Collection<? extends E> c) {
try {
boolean modified = false;
ListIterator<E> e1 = listIterator(index);
Iterator<? extends E> e2 = c.iterator();
while (e2.hasNext()) {
e1.add(e2.next());
modified = true;
}
return modified;
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
这个类是直接被LinkedList继承的一个抽象类,说实话我并不知道为什么需要这个类,这些方法在LinkedList中又被重写了。java集合类库不是一天写完的,可能在很多个版本更迭中需要这个抽象类,那么,它就这样出现了。
12. Map
以上11种是所有Collection继承下的接口和抽象类,从此以下是所有Map下的接口和抽象类。
public interface Map<K,V> {
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
V put(K key, V value);
V remove(Object key);
void putAll(Map<? extends K, ? extends V> m);
void clear();
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
interface Entry<K,V> {
K getKey();
V getValue();
V setValue(V value);
boolean equals(Object o);
int hashCode();
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getKey().compareTo(c2.getKey());
}
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getValue().compareTo(c2.getValue());
}
public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
Objects.requireNonNull(cmp);
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
}
public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
Objects.requireNonNull(cmp);
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
}
}
boolean equals(Object o);
int hashCode();
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
default void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Objects.requireNonNull(function);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
// ise thrown from function is not a cme.
v = function.apply(k, v);
try {
entry.setValue(v);
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
}
}
13. AbstractMap
和之前的其他被Abstract冠名的类相似,AbstractMap把Map的基本方法都实现了一遍,实际上这些方法还会被具体的HashMap等再实现,但在此类中实现,为其他人继承AbstractMap而创建自己的Map提供了一个方便。