前些天被问HashMap实现原理,表示都没怎么看过源码。。。就想从头看一遍。
java集合工具包java.util.。大致关系如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107/** * | * |Collection * | --AbstractCollection * | --AbstractList * | --AbstractSet * | --AbstractQueue * | --List :可重复,有存储顺序 * | --AbstractList * | --Vector :和ArrayList一样,但线程安全,所以效率低 * | --Stack * | --AbstractSequentialList * | --LinkedList :链表,查找慢(查找需要依次遍历),增删快(当前位置前后元素相连即可) * | --ArrayList :底层数组,查找快(数组可直接按照索引查找快),增删慢(涉及增容,拷贝) * | --CopyOnWriteArrayList * | --Set :不可重复,无存储顺序 * | --AbstractSet * | --HashSet :不需要排序使用效率高于TreeSet * | --LinkedHashSet :需要保留存储顺序,又要过滤重复元素时使用 * | --TreeSet :需要将元素排序时使用 * | --SortedSet * | --NavigableSet * | --Queue * | --Deque * | --AbstractQueue * | --PriorityQueue * |Map * | --ConcurrentMap * | --ConcurrentHashMap * | --SortedMap * | --NavigableMap * | --TreeMap * | --AbstractMap * | --HashMap * | --LinkedHashMap * | --WeakHashMap * | --IdentityHashMap * | --TreeMap * | --EnumMap */
主要分为Collection和Map两部分
Iterator
Collection集成Iterable接口,首先看Iterable接口,里面只有一个方法:
1
2Iterator<T> iterator();
Iterator接口共有三个方法,分别为:是否存在当前游标的下一个元素,获取下一个元素,删除当前元素
1
2
3
4
5public interface Iterator<E> { boolean hasNext(); E next(); void remove(); }
使用类似如下步骤可以迭代输出集合中的数据:
1
2
3
4
5Iterator iterator = list.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); }
可以使用CopyOnWriteArrayList代替ArrayList,ConcurrentHashMap代替HashMap;
或者使用Collections.synchronizedLsit(list)方法.
for-each循环内部也使用的Iterator遍历
ListIterator:
该接口继承Iterator,适用于List及其子类,并且增加了6个方法,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public interface ListIterator<E> extends Iterator<E> { boolean hasNext(); //判断游标后是否有元素 E next(); //返回游标后面一个元素,并且游标后移一位 boolean hasPrevious(); //判断游标前是否有元素 E previous(); //返回游标前面的元素,并且游标向前移动一位 int nextIndex(); //返回游标后面的索引位置 int previousIndex(); //返回游标前面的索引位置 void remove(); //删除迭代器操作的最后一个元素 void set(E e); //更新迭代器最后一次操作的元素 void add(E e); //在游标前面插入元素 }
Collection:
collection接口有两个分支,List和Set。这两个也都是接口,List是由存储顺序,可重复;Set无存储顺序,不可重复。
1
2
3
4
5public interface Collection<E> extends Iterable<E> { int size(); boolean isEmpty(); boolean contains(Object o); //是否包含指定元素 Iterator<E> iterator(); //获取迭代器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17Object[] toArray(); //返回一个包含集合中所有元素的数组 <T> T[] toArray(T[] a); //返回一个包含集合中所有元素的数组,运行时根据集合类型指定数组的类型 boolean add(E e); //添加元素 boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); //保留本集合和C集合共有的 void clear(); boolean equals(Object o); int hashCode(); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28public interface List<E> extends Collection<E> { boolean isEmpty(); boolean contains(Object o); //判断是否包含o Iterator<E> iterator(); Object[] toArray(); <T> T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean addAll(int index, Collection<? extends E> c); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); void clear(); boolean equals(Object o); //需重写,因为Object默认是地址比较 int hashCode(); //需重写 E get(int index); E set(int index, E element); void add(int index, E element); E remove(int index); int indexOf(Object o); //返回指定元素第一次出现的位置 int lastIndexOf(Object o); 返回指定元素最后一次出现的位置(倒叙遍历) ListIterator<E> listIterator(); ListIterator<E> listIterator(int index); //指定了游标的位置 List<E> subList(int fromIndex, int toIndex); //范围查询,左闭右开 }
Set:
set是没有重复元素的集合,API与Collection一样。
AbstractCollection:
是Collection的实现类,包含了一些具体实现方法以及几个抽象方法,是一个抽象类,AbstractSet和AbstractList继承它。
包含以下两个抽象方法:
1
2public abstract Iterator<E> iterator(); public abstract int size();
1
2
3
4public boolean add(E e) { throw new UnsupportedOperationException(); }
1
2
3protected AbstractCollection() { }
1
2
3
4public boolean isEmpty() { return size() == 0; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14public 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; }
转换成Object[]数组:使用Iterator遍历赋值给一个新建的数组。
这个方法的实现还确保了即使在迭代器期间修改了集合。比如说size的返回的大小不对还是会根据迭代器迭代到的元素的数量得到正确的数组
1
2
3
4
5
6
7
8
9
10
11
12public Object[] toArray() { // Estimate size of array; be prepared to see more or fewer elements Object[] r = new Object[size()]; Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { if (! it.hasNext()) // 如果迭代器的实际大小比size小,则使用Array.copyOf(r,i)截断当前的数组,然后直接返回 return Arrays.copyOf(r, i); r[i] = it.next(); } return it.hasNext() ? finishToArray(r, it) : r; //如果size小于迭代器的,则调用finishToArray() }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22private static <T> T[] finishToArray(T[] r, Iterator<?> it) { int i = r.length; //当前迭代的元素数量 while (it.hasNext()) { int cap = r.length; //当前数组的大小 if (i == cap) { //如果两个值一样,说明需要加大数组的长度,即增加cap。这里增加了0.5cap+1 int newCap = cap + (cap >> 1) + 1; if (newCap - MAX_ARRAY_SIZE > 0) //判断是否超过VM最大界限 newCap = hugeCapacity(cap + 1); //超过则调用该函数调整大小 r = Arrays.copyOf(r, newCap); } r[i++] = (T)it.next(); //将迭代器下一个元素放入数组,迭代数量+1 } return (i == r.length) ? r : Arrays.copyOf(r, i); //结束时根据已经迭代的元素数i,来复制当前数组到一个新的数组 }
1private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//AbstractCollection中定义
1
2
3
4
5
6
7
8
9private static int hugeCapacity(int minCapacity) {//用于确定数组极限的值 if (minCapacity < 0) // overflow throw new OutOfMemoryError ("Required array size too large"); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
这个方法将对象先试图填充到给定的数组a中,如果a的数组不够用了,则新建一个新数组来保存集合中的元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34public <T> T[] toArray(T[] a) { // Estimate size of array; be prepared to see more or fewer elements int size = size(); T[] r = a.length >= size ? a : //判断添加的数组a与原list长度哪个大 (T[])java.lang.reflect.Array .newInstance(a.getClass().getComponentType(), size); //创建一个新的、类型与a一样的、长度为size的数组 Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { if (! it.hasNext()) { //迭代器迭代完成 if (a == r) { //如果r引用的就是a r[i] = null; //i位为0 } else if (a.length < i) { //a的长度小于i,说明放不进a,则返回的是自建数组,对r后面的元素截取就可以了 return Arrays.copyOf(r, i); } else { //说明a数组是足够大的 System.arraycopy(r, 0, a, 0, i); //将r中的元素放入到a中, if (a.length > i) { a[i] = null; } } return a; } r[i] = (T)it.next(); } // more elements than expected return it.hasNext() ? finishToArray(r, it) : r; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public 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; }
1
2
3
4
5
6
7public boolean containsAll(Collection<?> c) { for (Object e : c) if (!contains(e)) return false; return true; }
1
2
3
4
5
6
7
8
9
10
11
12public boolean retainAll(Collection<?> c) { boolean modified = false; Iterator<E> it = iterator(); while (it.hasNext()) { if (!c.contains(it.next())) { it.remove(); modified = true; } } return modified; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public String toString() { Iterator<E> it = iterator(); if (! it.hasNext()) return "[]"; StringBuilder sb = new StringBuilder(); sb.append('['); for (;;) { E e = it.next(); sb.append(e == this ? "(this Collection)" : e); if (! it.hasNext()) return sb.append(']').toString(); sb.append(',').append(' '); } }
AbstractList:
1public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
实现了AbstractCollection的其中一个抽象方法interator()
1
2
3
4public Iterator<E> iterator() { return new Itr(); }
如果子类要使用add,set,remove方法,则需要重写,否则会报错UnsupportedOperationException
1
2
3
4public E set(int index, E element) { throw new UnsupportedOperationException(); }
该类提供一个抽象方法get,用于子类实现
1abstract public E get(int index);
AbstractList提供 Iterator, ListIterator 迭代器的实现类,分别为 Itr, ListItr;ListItr继承Itr
ListItr使用如下方法获取
1
2
3
4
5
6
7public ListIterator<E> listIterator(final int index) { rangeCheckForAdd(index);//用来检查索引是否超过范围 <0 >size return new ListItr(index); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41private class Itr implements Iterator<E> { int cursor = 0;//游标 int lastRet = -1;//上一次迭代到的位置,用完后置-1 int expectedModCount = modCount;//判断并发修改 public boolean hasNext() { return cursor != size(); } public E next() { checkForComodification();//判断并发修改 try { int i = cursor; E next = get(i); //调用子类实现的get方法 lastRet = i; //由迭代操作的话,会记录上一次迭代的位置 cursor = i + 1; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet);//需要子类实现remove,当前类会抛异常 if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { cursor = index; //指定游标位置 } public boolean hasPrevious() { return cursor != 0; } public E previous() { checkForComodification(); try { int i = cursor - 1; E previous = get(i); lastRet = cursor = i; //上次操作的位置 = i;游标 = i return previous; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public int nextIndex() {//下一个位置 return cursor; } public int previousIndex() { return cursor-1; } public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.set(lastRet, e); //子类方法,上次的位置还要在其中查询是否为-1 expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } 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(); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14public 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; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14public 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; }
1
2
3
4public void clear() { removeRange(0, size()); }
1
2
3
4
5
6
7
8protected void removeRange(int fromIndex, int toIndex) { ListIterator<E> it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i<n; i++) { it.next(); it.remove(); } }
equals和hashcode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public 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()) { //同时迭代当前集合和o集合,判断是否全都相同 E o1 = e1.next(); Object o2 = e2.next(); if (!(o1==null ? o2==null : o1.equals(o2))) return false; } return !(e1.hasNext() || e2.hasNext()); }
1
2
3
4
5
6
7public int hashCode() { int hashCode = 1; for (E e : this) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); return hashCode; }
1
2
3
4
5
6public List<E> subList(int fromIndex, int toIndex) { return (this instanceof RandomAccess ? new RandomAccessSubList<>(this, fromIndex, toIndex) : new SubList<>(this, fromIndex, toIndex)); }
1
2
3public interface RandomAccess { }
通常在操作List会先判断是否支持随机访问,是否是RandomAccess的实例,如果是,比如在遍历中就使用get(),而不是Iterator,因为前者更快。
RandomAccessSubList: 与SubList相比,就多一个RandomAccess
1
2
3
4
5
6
7
8class 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); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132class 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) { rangeCheck(index); checkForComodification(); return l.set(index+offset, element); } public E get(int index) { rangeCheck(index); checkForComodification(); return l.get(index+offset); } public int size() { checkForComodification(); return size; } public void add(int index, E element) { rangeCheckForAdd(index); checkForComodification(); l.add(index+offset, element); this.modCount = l.modCount; size++; } public E remove(int index) { rangeCheck(index); checkForComodification(); E result = l.remove(index+offset); this.modCount = l.modCount; size--; return result; } protected void removeRange(int fromIndex, int toIndex) { checkForComodification(); 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(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++; } }; } public List<E> subList(int fromIndex, int toIndex) { return new SubList<>(this, fromIndex, toIndex); } private void rangeCheck(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private void rangeCheckForAdd(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } private void checkForComodification() { if (this.modCount != l.modCount) throw new ConcurrentModificationException(); } }
最后
以上就是自然蜻蜓最近收集整理的关于Iterator、AbstractCollection、AbstractList的全部内容,更多相关Iterator、AbstractCollection、AbstractList内容请搜索靠谱客的其他文章。
发表评论 取消回复