Java 集合深入理解 :AbstractList类
Posted 踩踩踩从踩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 集合深入理解 :AbstractList类相关的知识,希望对你有一定的参考价值。
前言
AbstractList 此类提供 List 接口的骨干实现,从而最大限度地减少了实现由“随机访问”数据存储(如数组)支持的接口所需的工作。对于连续的访问数据(如链表),应优先使用AbstractSequentialList,而非此类, 可以了解该类也是很有必要的
全篇注释
/**
*此类提供了{@link List}的框架实现接口以最小化实现此接口所需的工作
*由“随机访问”数据存储(如数组)支持。对于顺序访问数据(如链表),{@link AbstractSequentialList}应该优先于这个类使用。<p>要实现一个不可修改的列表,程序员只需扩展这个类并为{@link#get(int)}和{@link List#size()size()}方法。
*<p>要实现可修改列表,程序员必须另外重写{@link#set(int,Object)set(int,E)}方法(否则抛出一个{@code UnsupportedOperationException})。如果列表是
*可变大小程序员还必须重写{@link#add(int,Object)add(int,E)}和{@link#remove(int)}方法。
*<p>程序员通常应该提供void(无参数)和collection构造函数,按照{@link Collection}接口中的建议规范。
*<p>与其他抽象集合实现不同,程序员是这样做的<i>不</i>必须提供迭代器实现;迭代器和
*列表迭代器是由这个类在“随机访问”之上实现的方法:
*{@link#get(int)},
*{@link#set(int,Object)set(int,E)},
*{@link#add(int,Object)add(int,E)}和
*{@link#remove(int)}。
*<p>此类中每个非抽象方法的文档描述了其具体实施。如果正在实现的集合允许更高效的实现。
* <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @author Josh Bloch
* @author Neal Gafter
* @since 1.2
*/
注释解析
1.框架实现接口以最小化实现此接口所需基本方法
2.由“随机访问”数据存储(如数组)支持
3.要实现一个不可修改的列表,程序员只需扩展这个类并为{@link#get(int)}和{@link List#size()size()}方法
4.要实现可修改列表,程序员必须另外重写 set(int,Object)set(int,E)
6.对于链表AbstractSequentialList应该优先于这个类使用;
7.如果add remove等方法 没有实现,则会抛出UnsupportedOperationException 异常的
这个和AbstractCollection 中的注释描述的很像,都利用的模板方法,保证一些基础方法的实现,然后如果要实现可修改的点,需要实现对应的方法
Java 集合深入理解 (八) :Collection接口和list接口深入理解
add 方法
抽象类是没有实现add方法的,如果继承者没有实现add(int index, E element)则会抛出UnsupportedOperationException异常
/**
*将指定的元素追加到此列表的末尾(可选)操作)。<p>支持此操作的列表可能会限制可以将元素添加到此列表中。特别是一些
*列表将拒绝添加空元素,其他列表将强制对可能添加的元素类型的限制。列表类应该在其文档中明确指定任何限制可以添加哪些元素。
*
* <p>This implementation calls {@code add(size(), e)}.
*
* <p>注意,这个实现抛出一个
* {@code UnsupportedOperationException} unless
* {@link #add(int, Object) add(int, E)} 被覆盖.
*
* @param 要附加到此列表的元素
* @return {@code true} (as specified by {@link Collection#add})
* @throws UnsupportedOperationException if the {@code add} 操作 表示此列表不支持
*
* @throws ClassCastException 如果指定元素的类
* 阻止将其添加到此列表
* @throws NullPointerException 如果指定的元素为null
* 列表不允许空元素
* @throws IllegalArgumentException 如果这个元素的某些属性
* 阻止将其添加到此列表
*/
public boolean add(E e) {
add(size(), e);
return true;
}
/**
* {@inheritDoc}
*
* <p>这个实现总是抛出一个
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
abstract public E get(int index);
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
throw new UnsupportedOperationException();
}
**抽象方法 **
继承者去实现 get(int index) set(int index, E element) remove(int index)
要不然在调用此方法时会抛出UnsupportedOperationException 异常
indexOf和lastIndexOf方法
抽象类提供了查找对象的方式
获取迭代器
一个从头开始寻找,一个从尾开始往前寻找,直到找到元素为止,包括调用的nextIndex 等方法,都是最后调用到get() 方法。
/**
* {@inheritDoc}
*
* <p>这个实现首先得到一个列表迭代器 (with
* {@code listIterator()}). 然后,它在列表上迭代,直到找到指定的元素或到达列表的末尾。
*
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
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;
}
/**
* {@inheritDoc}
*
* <p>这个实现首先得到一个指向末尾的列表迭代器
* 名单上的 (with {@code listIterator(size())}). 然后,它迭代
* 向后遍历列表,直到找到指定的元素,或者
* 到达列表的开头。
*
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
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;
}
批量操作
clear()方法
调用的removeRange方法
removeRange方法
通过将任何后续元素向左移动(减少其索引),元素来缩短列表,操作调用及其子列表。重写此方法以利用列表实现的内部可以改进此列表上,性能及其子列表。
fromIndex 是包含了的,toIndex是不包含,for (int i=0, n=toIndex-fromIndex; i<n; i++) {
这个关键点在这里,toIndex=fromIndex 该循环也是会进去一次的,所以fromIndex 也是会被删除的。 这在比如说arraylist中就被覆盖了,重写的,也是提高效率
/**
* 从此列表中删除所有元素(可选操作)。
* 此呼叫返回后,列表将为空。
*
* <p>This implementation calls {@code removeRange(0, size())}.
*
* <p>注意这个实现抛出
* {@code UnsupportedOperationException} unless {@code remove(int
* index)} or {@code removeRange(int fromIndex, int toIndex)} is
* overridden.
*
* @throws UnsupportedOperationException if the {@code clear} operation
* is not supported by this list
*/
public void clear() {
removeRange(0, size());
}
/**
*从此列表中删除索引介于{@code fromIndex}(包含)和{@code toIndex}(独占)。将任何后续元素向左移动(减少其索引)。
*这个调用通过{@code(toIndex-fromlindex)}元素来缩短列表。(如果{@code toIndex==fromIndex},则此操作无效。)
*<p>此方法由此列表上的{@code clear}操作调用及其子列表。重写此方法以利用列表实现的内部可以改进此列表上{@code clear}
操作的 性能及其子列表。
*<p>此实现在{@codefromindex},并重复调用{@codelistiterator.next}
*后跟{@code ListIterator.remove},直到完成整个范围
*已删除<b> 注意:如果{@codelistiterator.remove}需要线性
*时间,这个实现需要二次时间</b>
* @param fromIndex index of first element to be removed
* @param toIndex index after last element to be removed
*/
protected 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();
}
}
addAll 方法
addAll 这个公共的方法,通过调用抽象的 add(index++, e);去实现,确实效率会慢很多,所以像arraylist这些实现类,就重写该方法
/**
* {@inheritDoc}
*
* <p>此实现获取指定集合上的迭代器并对其进行迭代,插入从 在适当的位置迭代这个列表,一次一个,
* using {@code add(int, E)}.
* 为了提高效率,许多实现将覆盖此方法。
*
* <p>Note that this implementation throws an
* {@code UnsupportedOperationException} unless
* {@link #add(int, Object) add(int, E)} is overridden.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
boolean modified = false;
for (E e : c) {
add(index++, e);
modified = true;
}
return modified;
}
迭代器
这其中有两个迭代器通过iterator 和listIterator 方法给我们使用
1.Itr 迭代器
1.属性
cursor 后续调用下一个要返回的元素的索引。
lastRet 最近对下一个或的调用返回的元素的索引上一个。如果此元素被调用删除,则重置为-1移除。
也就是记录上个元素的索引,这在next方法中就能对比,如果remove了的话,就重置为-1;
2.next 和 remove方法
并在remove等操作中添加对lastRet 的判断, 防止多次删除等操作
2.ListItr
该迭代器 解释是实现依赖于备份列表,
从源码来说,相当于 Itr的增强,
set 方法,对节点的替换,
previous方法,后置遍历的方法
add 方法, 添加数据到末尾
Java 集合深入理解 (三) :java.util 包的集合中 fail-fast 快速失败机制
/**
*按正确的顺序返回此列表中元素的迭代器。<p>此实现返回迭代器接口,依赖于支持列表的{@code size()},
*{@code get(int)}和{@code remove(int)}方法。
*<p>请注意,此方法返回的迭代器将抛出{@link UnsupportedOperationException}响应其
*{@code remove}方法,除非列表的{@code remove(int)}方法已覆盖。
*<p>此实现可以在规范中所述的并发修改的面
*对于(protected){@link#modCount}字段。
* @return an iterator over the elements in this list in proper sequence
*/
public Iterator<E> iterator() {
return new Itr();
}
/**
* {@inheritDoc}
*
* <p>This implementation returns {@code listIterator(0)}.
*
* @see #listIterator(int)
*/
public ListIterator<E> listIterator() {
return listIterator(0);
}
/**
* {@inheritDoc}
*
*<p>此实现返回{@code ListIterator}接口,扩展了{@code迭代器}由{@code迭代器()}方法返回的接口。
*{@code ListIterator}实现依赖于备份列表{@code get(int)},{@code set(int,E)},{@code add(int,E)}
*以及{@code remove(int)}方法。<p>注意,此实现返回的列表迭代器将
*抛出{@link unsportDoperationException}来响应
*{@code remove}、{@code set}和{@code add}方法,除非列表的{@code remove(int)}、{@code set(int,E)和
*{@code add(int,E)}方法被重写。
*<p>此实现可以在
*并发修改的面,如规范中所述
*(受保护){@link\\modCount}字段。
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public ListIterator<E> listIterator(final int index) {
rangeCheckForAdd(index);
return new ListItr(index);
}
private class Itr implements Iterator<E> {
/**
* Index of element to be returned by subsequent call to next.
*/
int cursor = 0;
/**
*最近对下一个或的调用返回的元素的索引上一个。如果此元素被调用删除,则重置为-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.
*/
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();
}
}
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();
}
}
}
subList 操作
返回的是父集合的一部分视图 也就是 还是操作的原来那个集合,只是因为 指针限制,所以操作的,指针区间的那部分。
new 一个SubList 对象,并在提供 add 方法 或者remove方法,set等方法, 将原有的集合持有着,后续操作
/**
* {@inheritDoc}
*
*<p>这个实现返回一个包含子类的列表{@code AbstractList}。子类在私有字段中存储
*备份列表中子列表的偏移量,子列表的大小(在其生命周期内可能会发生变化)和
*{@code modCount}支持列表的值。有两种变体子类,其中一个实现{@code RandomAccess}。
*如果此列表实现{@code RandomAccess},则返回的列表将
*是实现{@code RandomAccess}的子类的实例。
*<p>子类的{@code set(int,E)},{@code get(int)},
*{@code add(int,E)},{@code remove(int)},{@code addAll(int,
*Collection)}和{@code removeRange(int,int)}方法
*委托给备份抽象列表中相应的方法,在边界检查索引并调整偏移量之后。这个
*{@code addAll(Collection c)}方法只返回{@code addAll(size,
*c)}。
*<p>方法{@CodeListIterator(int)}返回一个“包装器对象”在备份列表上的列表迭代器上,使用
*备份列表上的相应方法。{@code iterator}方法
*只返回{@code lisiterator()},和{@code size}方法只返回子类的{@code size}字段。
*<p>所有方法首先检查支持列表等于其预期值,并抛出
*{@code ConcurrentModificationException}如果不是。
*
* @throws IndexOutOfBoundsException if an endpoint index value is out of range
* {@code (fromIndex < 0 || toIndex > size)}
* @throws IllegalArgumentException if the endpoint indices are out of order
* {@code (fromIndex > toIndex)}
*/
public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<>(this, fromIndex, toIndex) :
new SubList<>(this, fromIndex, toIndex));
}
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) {
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 fromIndexJava 集合深入理解 :AbstractCollection类
深入理解java集合框架之---------Arraylist集合 -----添加方法