JDK源码学习 —— 集合框架抽象类:AbstractList

顶级接口定义功能,下一步就是抽象类了,抽象类实现了这一系列最通用的方法,List 这一继承分支的抽象类是 AbstractList

老规矩,先读注释,再看方法,因为现在涉及到实现了,所以还需要看具体的实现。

类结构

image-20201014094105769

类注释

This class provides a skeletal(骨架) implementation of the List interface to minimize the effort(努力) required to implement this interface backed by a “random access“ data store (such as an array). For sequential(按顺序地) access data (such as a linked list), AbstractSequentialList should be used in preference to this class.

这个类(AbstracList) 提供了 List 接口的最基本的实现,最大程度地减少了实现一个随机访问数据存储(例如数组)的类需要做的工作。 如果你需要实现一个顺序存储(例如链表的类,则应该优先使用 AbstractSequentialList,而不是这个 AbstactList

To implement an unmodifiable list, the programmer needs only to extend this class and provide implementations for the get(int) and size() methods.

如果要实现一个不可变的 List,则开发者只需要集成这个类,并且只提供 get(int) 以及 size() 方法的具体实现即可。

To implement a modifiable list, the programmer must additionally override the set(int, E) method (which otherwise throws an UnsupportedOperationException). If the list is variable-size the programmer must additionally override the add(int, E) and remove(int) methods.

如果要实现一个可修改的列表,开发者必须重写 set(int,E) 函数,否则使用这个方法会抛出 UnsupportedOperationException 异常。如果 List 是可变大小的,则还需要实现 addremove 方法 来添加/删除 元素。

The programmer should generally provide a void (no argument) and collection constructor, as per the recommendation in the Collection interface specification.

根据之前 Collection 接口规范中的建议,需要有两个构造函数:一个无参构造,一个入参是一个 Collection 的构造函数。

Unlike the other abstract collection implementations, the programmer does not have to provide an iterator implementation; the iterator and list iterator are implemented by this class, on top of the “random access” methods: get(int), set(int, E), add(int, E) and remove(int).

与其他 抽象的 集合实现类不同,开发者不需要提供 迭代器 Iterator 的实现, IteratorListIterator 的实现都由这个类来提供(AbstractList),迭代器提供了以下方法:

  • get
  • set
  • add
  • remove

The documentation for each non-abstract method in this class describes its implementation in detail. Each of these methods may be overridden if the collection being implemented admits a more efficient implementation.
This class is a member of the Java Collections Framework.

AbstractList 中的每个非抽象方法的文档都详细描述了方法的实现。 如果正在实现的集合类需要更有效地特定实现,则可以覆盖 AbstractList 中的每个方法。

这个类是 Java Collection 集合框架中的成员。

小结:

AbstractList 提供了迭代器的实现,以及主要方法的实现,如果具体的实现类有需求的话也可以覆盖任何方法。并且类中每个方法都提供了具体的文档,所以要多看下方法的文档了。

看了下类中的实现,最主要的还是提供了 Iterator 和 ListIterator 的 实现,下面主要就看看这两个部分。

Iterator

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
private class Itr implements Iterator<E> {
/**
* Index of element to be returned by subsequent call to next.
* 游标,调用 next 返回的元素的索引,从 0 (第一个元素)开始
*/
int cursor = 0;

/**
* Index of element returned by most recent call to next or
* previous. Reset to -1 if this element is deleted by a call
* to remove.
* 最近一次调用 next 或 previous 返回的元素的索引,如果调用了 remove 删除元素,则重置为 -1
*/
int lastRet = -1;

/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected(未被发现的) concurrent modification.
* 内置的计数器,ConcurrentModificationException 并发修改异常的源头,如果 ExpectModCount 与期望值不一样,说明有其他线程修改了值,于是抛出并发修改异常
*/
int expectedModCount = modCount;

public boolean hasNext() {
return cursor != size();
}

public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
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);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}

final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}

ListIterator

之前读注释的时候提到了, List 实现了自己独有的 ListIterator,其功能比 Iterator 多了 元素的替换、插入、双向访问。于是这里看看具体是怎么做的

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
private 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;
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);
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();
}
}
}

这里的双向访问主要是 ListIterator 提供了 previousnext 两种遍历方法,previous 是返回上一个元素, next 返回下一个元素。

类方法

大概看了一下,其他的方法也基本上没有具体的实现,看来需要继续往下看了。

  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2015-2020 Ahri
  • Powered by Hexo Theme Ayer
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信