这里分析一下util包下集合的抽象类的源码,包括AbstractCollection、AbstractList、AbstractMap、AbstractSet
抽象类、接口继承关系图和实现关系图:
1.AbstractCollection
AbstractCollection抽象类是所有list、set实现类的顶层父类,是为继承而设计。
首先AbstractCollection实现了Collection接口,源码如下:
public abstract class AbstractCollection<E> implements Collection<E> { }
包含唯一的抽象方法用于返回迭代器,源码如下:
public abstract Iterator<E> iterator();
可以看到抽象方法强制交给子类实现。
例如AbstractList的iterator()返回的迭代器实例由他的非静态成员内部类Itr提供,它还有个非静态成员内部类ListItr支持反向遍历。
例如AbstractSet并没有覆盖iterator()方法,而是完全交给子类实现,如HashSet覆盖的iterator()方法返回的是HashMap.keySet().iterator()的迭代器(因为HashSet基于HashMap实现),而这个迭代器被申明为HashMap的成员内部类EntryIterator。
值的注意的就是几个toArray方法的实现。一个是不指定数组长度,如果长度不够则以一半加一的方式动态增长。另一个是指定一个长度(也可能不够用),源码如下:
//不指定长度进行转化 public Object[] toArray() { Object[] r = new Object[size()]; Iterator<E> it = iterator(); //以size()返回值最为长度创建数组 for (int i = 0; i < r.length; i++) { //迭代器能够迭代的次数<数组长度,则直接截断当前数组并返回 if (! it.hasNext()) return Arrays.copyOf(r, i);//截断数组返回 //迭代器每返回一个值就保存到数组中 r[i] = it.next(); } //迭代器能够迭代的次数>数组长度,剩下没被迭代的元素再组成一个迭代器 return it.hasNext() ? finishToArray(r, it) : r; } private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; @SuppressWarnings("unchecked") private static <T> T[] finishToArray(T[] r, Iterator<?> it) { //i保存已经迭代过的元素个数 int i = r.length; while (it.hasNext()) { //从已经迭代过的元素的位置开始继续迭代,cap保存数组长度 int cap = r.length; //判断已经填充元素个数是否查过数组长度,这里相同说明数组刚好被用完,需要建立更长的新数组 if (i == cap) { //newCap保存新数组长度,即原来一半加1 int newCap = cap + (cap >> 1) + 1; //这一步判断新数组长度是否超过最大数组大小 if (newCap - MAX_ARRAY_SIZE > 0) //如果超过则调用hugeCapacity动态调整得到一个新的长度 newCap = hugeCapacity(cap + 1); //复制成一个新数组,且新数组长度为newCap r = Arrays.copyOf(r, newCap); } //从i开始继续填充数组 r[i++] = (T)it.next(); } return (i == r.length) ? r : Arrays.copyOf(r, i); } //如果数组长度值增长到超过最大数组长度,则动态调整得到一个合理的长度 private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) throw new OutOfMemoryError ("Required array size too large"); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } //指定一个长度进行转换 @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { int size = size(); //比较Set的size和你指定的数组长度哪个更长,以更长的值作为长度创建数组,这里利用反射指定数组元素类型 //r指向a,或者r执行以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()) { //r指向a说明用户传入的数组大于size,可以放下所有元素,直接返回a即可 if (a == r) { r[i] = null; } //r不指向a而是执行以size新建的数组,需要截断返回 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(); } //同上 return it.hasNext() ? finishToArray(r, it) : r; }
剩下的就是一般的方法。有的给出了简单实现,有的仅抛出异常并要求子类扩展。源码如下:
protected AbstractCollection() { } public abstract int size(); public boolean isEmpty() { return size() == 0; } public boolean contains(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) if (it.next()==null) return true; } else { while (it.hasNext()) if (o.equals(it.next())) return true; } return false; } public boolean add(E e) { throw new UnsupportedOperationException(); } public boolean remove(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) { if (it.next()==null) { it.remove(); return true; } } } else { while (it.hasNext()) { if (o.equals(it.next())) { it.remove(); return true; } } } return false; } public boolean containsAll(Collection<?> c) { for (Object e : c) if (!contains(e)) return false; return true; } public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; } public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); boolean modified = false; Iterator<?> it = iterator(); while (it.hasNext()) { if (c.contains(it.next())) { it.remove(); modified = true; } } return modified; } public boolean retainAll(Collection<?> c) { Objects.requireNonNull(c); boolean modified = false; Iterator<E> it = iterator(); while (it.hasNext()) { if (!c.contains(it.next())) { it.remove(); modified = true; } } return modified; } public void clear() { Iterator<E> it = iterator(); while (it.hasNext()) { it.next(); it.remove(); } } public String toString() { //略 }
2.AbstractList
AbstractList 类文件中包含了三个类,依次继承关系是:AbstractList->SubList->RandomAccessSubList。下面依次分析其源码。
(a)AbstractList 类
首先抽象类继承AbstractCollection并实现了List接口,源码如下:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}
简单实现了基本的接口方法,包括基本的增、删、查等,源码如下:
//这个值用于快速失败机制 protected transient int modCount = 0; //构造函数 protected AbstractList() {} //add public boolean add(E e) { add(size(), e); return true; } //add public void add(int index, E element) { //方法仅抛出异常,具体交给子类实现 throw new UnsupportedOperationException(); } //get abstract public E get(int index); //set public E set(int index, E element) { throw new UnsupportedOperationException(); } //remove public E remove(int index) { throw new UnsupportedOperationException(); } //返回元素O在集合中第一次出现的位置 public int indexOf(Object o) { ListIterator<E> it = listIterator(); if (o==null) { while (it.hasNext()) if (it.next()==null) return it.previousIndex(); } else { while (it.hasNext()) if (o.equals(it.next())) return it.previousIndex(); } return -1; } //返回元素O在集合中最后一次出现的位置 public int lastIndexOf(Object o) { ListIterator<E> it = listIterator(size()); if (o==null) { while (it.hasPrevious()) if (it.previous()==null) return it.nextIndex(); } else { while (it.hasPrevious()) if (o.equals(it.previous())) return it.nextIndex(); } return -1; } //清空 public void clear() { //调用按照范围删除 removeRange(0, size()); } //按照范围删除 protected void removeRange(int fromIndex, int toIndex) { //调用listIterator返回一个迭代器内部类的实例 ListIterator<E> it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i<n; i++) { it.next(); it.remove(); } } //添加子集合到index指定位置 public boolean addAll(int index, Collection<? extends E> c) { //add前检查index位置是否合法 rangeCheckForAdd(index); boolean modified = false; for (E e : c) { add(index++, e); modified = true; } return modified; } //检查添加的位置index是否合法 private void rangeCheckForAdd(int index) { if (index < 0 || index > size()) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //通过迭代器挨个调用equals public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof List)) return false; ListIterator<E> e1 = listIterator(); ListIterator<?> e2 = ((List<?>) o).listIterator(); while (e1.hasNext() && e2.hasNext()) { E o1 = e1.next(); Object o2 = e2.next(); if (!(o1==null ? o2==null : o1.equals(o2))) return false; } return !(e1.hasNext() || e2.hasNext()); } public int hashCode() { int hashCode = 1; for (E e : this) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); return hashCode; }
同时实现了list接口的iterator()方法返回集合迭代器,迭代器由内部类提供实例,这个迭代器实现了基本的next、remove、快速失败检查,源码如下:
//返回迭代器,由Itr内部类提供实例 public Iterator<E> iterator() { return new Itr(); } //迭代器私有内部类 private class Itr implements Iterator<E> { //访问游标(记录下一次next方法需要访问的下标) int cursor = 0; //记录最近调用next()或者previous()方法时返回元素的索引 //如果调用了remove()方法则将它的值重置为-1 int lastRet = -1; //快速失败机制 int expectedModCount = modCount; public boolean hasNext() { return cursor != size(); } public E next() { //检查快速失败机制 checkForComodification(); try { //从第0个开始访问 int i = cursor; E next = get(i); //设置最近调用next返回的下标 lastRet = i; //设置下一次调用next需要访问的下标 cursor = i + 1; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } //从集合中删除迭代器返回的最后一个元素 public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { //删除最近被next访问的元素 AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } //快速失败检查 //快速失败:迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(元素增加、删除、结构修改等),则会抛出异常 //其中modCount为外部类(集合类)变量,expectedModCount为内部类(迭代器)变量,在创建内部类对象(迭代器)时将他们设置为一样 //比如子类ArrayList的ensureExplicitCapacity方法中,会使得modCount加1,如果线程1使得modCount这个值加1 //而线程二中调用的迭代器的expectedModCount值还是和原来的modCount相等,所以使得两个值在此刻不相等就会抛出异常 final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
可以看到迭代器主要做这几件工作
判断迭代位置、下标移动:cursor记录下一次调用next()会访问的位置,lastRed记录刚刚调用next()访问的位置这个位置可能被删除,最后比较cursor和size判断是否迭代到头
元素删除、删除造成的影响:调用AbstractList.this.remove删除lastRed位置的元素,删除前先确保它不是-1
防止多个迭代器相互影响:快速失败机制
上述内部类还有一个子类实现,也是作为内部类存在于AbstractList中,并提供listIterator()方法返回一个list迭代器,只是增加了几个方法以支持反向遍历,源码如下:
//返回迭代器,由ListItr内部类提供实例 public ListIterator<E> listIterator(final int index) { //add操作的下标检查 rangeCheckForAdd(index); //返回list迭代器 return new ListItr(index); } //list迭代器 private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { cursor = index; } //反向遍历时判断是否有下一个元素 //游标cursor初始为0就是第一个元素 public boolean hasPrevious() { return cursor != 0; } //访问cursor所在的元素 public E previous() { checkForComodification(); try { //由于是反向遍历,所以游标向前移动 int i = cursor - 1; E previous = get(i); lastRet = cursor = i; return previous; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public int nextIndex() { return cursor; } public int previousIndex() { return cursor-1; } //lastRet记录了遍历时当前元素的游标,给他重新set值 public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.set(lastRet, e); expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } //在cursor位置加入集合 public void add(E e) { checkForComodification(); try { int i = cursor; AbstractList.this.add(i, e); lastRet = -1; cursor = i + 1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } }
接下来提供了一个subList(a,b)方法返回集合下标a,b范围间的子列表,方法源码如下:
//返回下标范围之间的所有元素 public List<E> subList(int fromIndex, int toIndex) { //判断当前调用此方法的AbstractList子类是否继承了RandomAccess接口(是否支持快速访问) //支持:返回RandomAccessSubList(继承自SubList)实例 //不支持:返回SubList实例 return (this instanceof RandomAccess ? new RandomAccessSubList<>(this, fromIndex, toIndex) : new SubList<>(this, fromIndex, toIndex)); }
(b)上述SubList和RandomAccessSubList类均继承自AbstractList,也就是AbstractList文件的另外两个class,源码如下:
//子集合类,通过继承AbstractList来扩展 class SubList<E> extends AbstractList<E> { //持有一个父类的引用,下面大部分操作都使用父类引用来调用,防止由于父类方法自用性对子类的干扰,这是一种复合转发的思想 private final AbstractList<E> l; private final int offset; private int size; //构造方法 SubList(AbstractList<E> list, int fromIndex, int toIndex) { if (fromIndex < 0) throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > list.size()) throw new IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex +") > toIndex(" + toIndex + ")"); l = list; offset = fromIndex; size = toIndex - fromIndex; this.modCount = l.modCount; } public E set(int index, E element) { //省略 return l.set(index+offset, element); } public E get(int index) { //省略 return l.get(index+offset); } public int size() { checkForComodification(); return size; } public void add(int index, E element) { //省略 l.add(index+offset, element); this.modCount = l.modCount; size++; } public E remove(int index) { //省略 E result = l.remove(index+offset); this.modCount = l.modCount; size--; return result; } protected void removeRange(int fromIndex, int toIndex) { //省略 l.removeRange(fromIndex+offset, toIndex+offset); this.modCount = l.modCount; size -= (toIndex-fromIndex); } public boolean addAll(Collection<? extends E> c) { return addAll(size, c); } public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); int cSize = c.size(); if (cSize==0) return false; checkForComodification(); l.addAll(offset+index, c); this.modCount = l.modCount; size += cSize; return true; } public Iterator<E> iterator() { return listIterator(); } public ListIterator<E> listIterator() { return listIterator(0); } //迭代器使用匿名类实例直接return,而不像父类那样使用非静态成员内部类 public ListIterator<E> listIterator(final int index) { checkForComodification(); rangeCheckForAdd(index); return new ListIterator<E>() { private final ListIterator<E> i = l.listIterator(index+offset); public boolean hasNext() { return nextIndex() < size; } public E next() { if (hasNext()) return i.next(); else throw new NoSuchElementException(); } public boolean hasPrevious() { return previousIndex() >= 0; } public E previous() { if (hasPrevious()) return i.previous(); else throw new NoSuchElementException(); } public int nextIndex() { return i.nextIndex() - offset; } public int previousIndex() { return i.previousIndex() - offset; } public void remove() { i.remove(); SubList.this.modCount = l.modCount; size--; } public void set(E e) { i.set(e); } public void add(E e) { i.add(e); SubList.this.modCount = l.modCount; size++; } }; } //其他方法省略 } //RandomAccess接口是个标记接口,表明这个类支持随机快速读取,目的是允许一般的算法更改其行为,从而在将其应用到随机或连续访问列表时能提供良好的性能。 class RandomAccessSubList<E> extends SubList<E> implements RandomAccess { RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) { super(list, fromIndex, toIndex); } //按照范围获取子集合 public List<E> subList(int fromIndex, int toIndex) { return new RandomAccessSubList<>(this, fromIndex, toIndex); } }
可以看到SubList持有一个父类的私有引用,这是由于子类实现直接调用从父类继承的方法会受到父类方法自用性的干扰,所以这里使用了复合转发的思想。这部分具体参考effective java这本书。
3. AbstractMap
分析如下,AbstractMap虽然是集合抽象类,但是他没有实现Collections接口,而是实现的Map接口。
(a)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(); //key不可重以Set存储 Set<K> keySet(); //value可重不能以Set存储 Collection<V> values(); //将每个键值对封装成Entry然后添加到Set集合中 Set<Map.Entry<K, V>> entrySet(); boolean equals(Object o); int hashCode(); //下面方法均给出默认实现,接口实现类可以不重写这些方法,也可以将他们覆盖 //按照key查找value,如果没有该映射返回默认值defaultValue 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); //本质是拿到Entry的Set集合然后用for循环遍历 for (Map.Entry<K, V> entry : entrySet()) { K k; V v; try { k = entry.getKey(); v = entry.getValue(); } catch(IllegalStateException ise) { 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) { throw new ConcurrentModificationException(ise); } v = function.apply(k, v); try { entry.setValue(v); } catch(IllegalStateException ise) { throw new ConcurrentModificationException(ise); } } } //如果key与value未关联,或者key关联null,此方法将他们关联并返回null default V putIfAbsent(K key, V value) { V v = get(key); if (v == null) { v = put(key, value); } return v; } //如果map有key,value这样一个Entry,则删除这个Entry default boolean remove(Object key, Object value) { Object curValue = get(key); if (!Objects.equals(curValue, value) || (curValue == null && !containsKey(key))) { return false; } remove(key); return true; } //如果map有key,value这样一个Entry,则替换其value default boolean replace(K key, V oldValue, V newValue) { Object curValue = get(key); if (!Objects.equals(curValue, oldValue) || (curValue == null && !containsKey(key))) { return false; } put(key, newValue); return true; } //如果map存在这样一对映射,则替换value default V replace(K key, V value) { V curValue; if (((curValue = get(key)) != null) || containsKey(key)) { curValue = put(key, value); } return curValue; } //如果key没有对应的value,用mappingFunction计算一个结果 //如果结果不为null,则作为value插入 //如果结果为null,则不插入任何映射 default V computeIfAbsent(K key,Function<? super K, ? extends V> mappingFunction) { Objects.requireNonNull(mappingFunction); V v; if ((v = get(key)) == null) { V newValue; if ((newValue = mappingFunction.apply(key)) != null) { put(key, newValue); return newValue; } } return v; } default V computeIfPresent(K key,BiFunction<? super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue; if ((oldValue = get(key)) != null) { V newValue = remappingFunction.apply(key, oldValue); if (newValue != null) { put(key, newValue); return newValue; } else { remove(key); return null; } } else { return null; } } //利用指定key和value计算一个新映射 default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue = get(key); V newValue = remappingFunction.apply(key, oldValue); if (newValue == null) { if (oldValue != null || containsKey(key)) { remove(key); return null; } else { return null; } } else { put(key, newValue); return newValue; } } //如果指定key没有value,或者其value为null,则将其改为给定的非null的value. default V merge(K key, V value,BiFunction<? super V, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); V oldValue = get(key); V newValue = (oldValue == null) ? value : remappingFunction.apply(oldValue, value); if(newValue == null) { remove(key); } else { put(key, newValue); } return newValue; } interface Entry<K,V> { K getKey(); V getValue(); V setValue(V value); boolean equals(Object o); int hashCode(); //返回key比较器,按照key自然顺序排序 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()); } //返回value比较器,按照value自然顺序排序 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()); } //返回key比较器,按照传入比较器排序 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()); } //返回value比较器,按照传入比较器排序 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()); } } }
可以看到Map接口有一个内部成员接口Entry用来封装键值对以方便迭代和遍历。并提供keySet和values集合保存键值。
(b)AbstractMap类
首先他继承Map接口,源码如下:
public abstract class AbstractMap<K,V> implements Map<K,V> { }
包含两个不可序列化、线程可见的键集合、值集合域,源码如下:
//key集合(不可重)带有线程可见性 transient volatile Set<K> keySet; //value集合(可重)带有线程可见性 transient volatile Collection<V> values;
除Map接口中已经有默认实现的方法外,他实现了基本一系列查、删方法,源码如下:
protected AbstractMap() { } public int size() { return entrySet().size(); } public boolean isEmpty() { return size() == 0; } //按value查找(value可以为null) public boolean containsValue(Object value) { //通过Set迭代器遍历每个Entry对象 Iterator<Entry<K,V>> i = entrySet().iterator(); //value可以为null if (value==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getValue()==null) return true; } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (value.equals(e.getValue())) return true; } } return false; } //按key查找(key可以为null) public boolean containsKey(Object key) { Iterator<Map.Entry<K,V>> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) return true; } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) return true; } } return false; } //按key查找,返回value public V get(Object key) { Iterator<Entry<K,V>> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) return e.getValue(); } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) return e.getValue(); } } return null; } //删除 public V remove(Object key) { //获取的Set的迭代器 Iterator<Entry<K,V>> i = entrySet().iterator(); Entry<K,V> correctEntry = null; if (key==null) { while (correctEntry==null && i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) correctEntry = e; } } else { while (correctEntry==null && i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) correctEntry = e; } } V oldValue = null; if (correctEntry !=null) { oldValue = correctEntry.getValue(); //底层调用Set的迭代器的remove()方法,删除整个Entry对象 i.remove(); } return oldValue; } //清空 public void clear() { //调用的是Set迭代器的clear()方法 entrySet().clear(); } //put,仅抛出异常由子类实现 public V put(K key, V value) { throw new UnsupportedOperationException(); } //putAll,将待put的子Map获取其EntrySet,挨个遍历Entry对象,并挨个put到最终Map里 public void putAll(Map<? extends K, ? extends V> m) { for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) put(e.getKey(), e.getValue()); }
可以看到他除put(key,value)方法仅抛出异常而交给子类实现外,其他的containsValue(value)、containsValue(key)、get(key)、remove()、clear()等方法均是利用entrySet()返回Set(Entry)集合的方法、或者Set(Entry)集合的迭代器的方法来实现的。
entrySet()方法是本类唯一的抽象方法,必须由子类扩展,源码如下:
//返回Entry的Set集合 public abstract Set<Entry<K,V>> entrySet();
成员方法keySet()给成员keySet赋值的同时,返回这个Set集合,源码如下:
//给成员keySet赋值,并返回 public Set<K> keySet() { if (keySet == null) { //新建一个AbstractSet抽象类实例,同时实现抽象类相关方法 keySet = new AbstractSet<K>() { //iterator()返回一个匿名Iterator接口实例,接口所有方法都用Entry的Set集合的迭代器 public Iterator<K> iterator() { return new Iterator<K>() { private Iterator<Entry<K,V>> i = entrySet().iterator(); public boolean hasNext() { return i.hasNext(); } public K next() { return i.next().getKey(); } public void remove() { i.remove(); } }; } //size() public int size() { return AbstractMap.this.size(); } //isEmpty() public boolean isEmpty() { return AbstractMap.this.isEmpty(); } //clear() public void clear() { AbstractMap.this.clear(); } //contains(Object k) public boolean contains(Object k) { return AbstractMap.this.containsKey(k); } }; } return keySet; }
可以看到keySet指向的是一个AbstractSet抽象类的匿名实现,这个匿名实现的迭代器相关的方法底层都调用的是从Entry的Set集合获取的迭代器,迭代器之外的方法都是AbstractMap.this方式调用本类的实现(因为这些方法没有什么扩展性,子类不需要自己实现,子类调用父类AbstractMap的就好)。
同样的还有成员方法values(),给成员values赋值的同时返回一个AbstractCollection抽象类的匿名实现,其迭代器相关方法也是用的Entry的Set集合的迭代器,之外的方法同样也是利用AbstractMap.this调用本类实现,源码如下:
//给成员values赋值,并返回 public Collection<V> values() { if (values == null) { values = new AbstractCollection<V>() { public Iterator<V> iterator() { return new Iterator<V>() { private Iterator<Entry<K,V>> i = entrySet().iterator(); public boolean hasNext() { return i.hasNext(); } public V next() { return i.next().getValue(); } public void remove() { i.remove(); } }; } public int size() { return AbstractMap.this.size(); } public boolean isEmpty() { return AbstractMap.this.isEmpty(); } public void clear() { AbstractMap.this.clear(); } public boolean contains(Object v) { return AbstractMap.this.containsValue(v); } }; } return values; }
剩下的就是一些基本的Object公共方法,值得注意的是他们大部分都使用了Entry的Set集合的迭代器,源码如下:
//equals() public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Map)) return false; Map<?,?> m = (Map<?,?>) o; if (m.size() != size()) return false; try { //获取Entry的Set的迭代器,遍历时挨个比较Entry对象 Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) { Entry<K,V> e = i.next(); K key = e.getKey(); V value = e.getValue(); if (value == null) { if (!(m.get(key)==null && m.containsKey(key))) return false; } else { if (!value.equals(m.get(key))) return false; } } } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } return true; } public int hashCode() { int h = 0; Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) h += i.next().hashCode(); return h; } public String toString() { Iterator<Entry<K,V>> i = entrySet().iterator(); if (! i.hasNext()) return "{}"; StringBuilder sb = new StringBuilder(); sb.append('{'); for (;;) { Entry<K,V> e = i.next(); K key = e.getKey(); V value = e.getValue(); sb.append(key == this ? "(this Map)" : key); sb.append('='); sb.append(value == this ? "(this Map)" : value); if (! i.hasNext()) return sb.append('}').toString(); sb.append(',').append(' '); } } protected Object clone() throws CloneNotSupportedException { AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone(); result.keySet = null; result.values = null; return result; } private static boolean eq(Object o1, Object o2) { return o1 == null ? o2 == null : o1.equals(o2); }
AbstractMap类中还包含了两个成员内部类SimpleEntry和SimpleImmutableEntry,他们是父子关系且实现了Entry接口,区别在于一个values是final,另一个不是final的,源码如下:
//静态成员内部类SimpleEntry,实现了Entry接口 public static class SimpleEntry<K,V> implements Entry<K,V>, java.io.Serializable { private static final long serialVersionUID = -8499721149061103585L; //key不可变 private final K key; //value可变 private V value; public SimpleEntry(K key, V value) { this.key = key; this.value = value; } public SimpleEntry(Entry<? extends K, ? extends V> entry) { this.key = entry.getKey(); this.value = entry.getValue(); } public V setValue(V value) { V oldValue = this.value; this.value = value; return oldValue; } public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry<?,?> e = (Map.Entry<?,?>)o; return eq(key, e.getKey()) && eq(value, e.getValue()); } //其他省略 } //静态成员内部类,实现Entry接口 public static class SimpleImmutableEntry<K,V> implements Entry<K,V>, java.io.Serializable{ private static final long serialVersionUID = 7138329143949025153L; //key和value均不可变 private final K key; private final V value; public SimpleImmutableEntry(K key, V value) { this.key = key; this.value = value; } public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) { this.key = entry.getKey(); this.value = entry.getValue(); } public V setValue(V value) { throw new UnsupportedOperationException(); } public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry<?,?> e = (Map.Entry<?,?>)o; return eq(key, e.getKey()) && eq(value, e.getValue()); } //其他省略 }
4. AbstractSet
首先AbstractSet继承了AbstractCollection实现了Set接口,源码如下:
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> { }
比较简单,就是equals()、removeAll()均是从参数的集合对象中获取迭代器执行后续操作,源码如下:
//构造方法 protected AbstractSet() { } //equals() public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Set)) return false; Collection<?> c = (Collection<?>) o; if (c.size() != size()) return false; try { //调用了containsAll(c)方法判断是否包含全部元素 //这个方法来自父类实现的接口的接口方法Collection //父类默认实现是利用for循环调用contains(e)方法 return containsAll(c); } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } } //hashCode() 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; } //removeAll() public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); boolean modified = false; //获取集合的迭代器,使用迭代器的remove()方法循环删除 if (size() > c.size()) { for (Iterator<?> i = c.iterator(); i.hasNext(); ) modified |= remove(i.next()); } else { for (Iterator<?> i = iterator(); i.hasNext(); ) { if (c.contains(i.next())) { i.remove(); modified = true; } } } return modified; }
5.并行迭代器Spliterator<T>
jdk8新增了并行迭代器Spliterator,然后在Iterable接口中定义了新的函数返回并行迭代器对象。集合抽象类的子类均给出了Spliterator接口的成员内部类实现,并使用ireartor新增的方法返回这个并行迭代器对象。现依次分析接口、抽象类。
首先查看Iterable接口的相关方法,部分代码如下:
public interface Iterable<T> { default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
可以看到接口使用default实现默认方法,当实现类没有覆盖spliterator()时则使用Spliterators.spliteratorUnknownSize(iterator(), 0)返回一个默认的并行迭代器,Spliterators这个类比较复杂。先查看Spliterator接口,源码如下: