您的位置:首页 > 编程语言 > Java开发

java——深入java.util包(collection接口之AbstractList)

2017-05-25 10:40 501 查看
深入了解下AbstractList这个抽象类,该类继承AbstractCollect实现List接口,

先看下类下有哪些东西,基本上都是实现父级的方法



它有两个私有的内部类如下



方法概要

remove()就是直接抛出异常,有两个重载的add()方法,第一个传入一个对象,然后将该size和引用传参,调用第二个add方法,直接抛出异常,不管是哪个,最终都是抛出异常

public boolean add(E e) {
add(size(), e);
return true;
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}


indexOf(Object o)方法。就是传入一个对象,然后对集合迭代通过equals和==分别匹配,如果存在就返回它的前一个指针位置,所有当第一个元素就匹配的时候,返回值是0,如果没有就返回-1。

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;
}


lastIndexOf(Object o)方法,是返回该对象在集合中最后的位置,先获取迭代,不过此处是从尾部开始,向前索引,while条件是前面是否还有元素。通过==和equals匹配,如果匹配到就返回它的下一个指针位置。没有匹配到就返回-1,

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 static void main(String[] args) {
List c=new ArrayList();
c.add("3");
c.add("1");
c.add("1");
c.add("4");

System.out.println(c.lastIndexOf("1"));//打印结果:2

}


clear()方法没啥好说,

addAll()方法,传入两个参数,index是要插入
4000
的位置, 调用rangeCheckForAdd(index)该方法,检查位置是否越界,然后定义修改,遍历并调用上面的add方法,最后返回true,传入集合为空的话不会添加任何东西。

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()方法就是直接new 内部类对象Itr。

public Iterator<E> iterator() {
return new Itr();
}


listIterator()方法,另一个重载的表示指定位置开始迭代,没有指定位置就是从0开始,然后构造一个它的内部类对象ListItr,这个下面再说

public ListIterator<E> listIterator(final int index) {
rangeCheckForAdd(index);

return new ListItr(index);
}
public ListIterator<E> listIterator() {
return listIterator(0);
}


下面是两个私有内部类,实现了Iterator接口,并且定义了几个属性, int cursor = 0; int lastRet = -1; int expectedModCount = modCount;

接着定义了hasNext()方法,该方法就是判断如果不相等于就返回true;

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


有hasNext方法,必须的next()方法,先检查,因为Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁,如果迭代过程中被改变,那么抛ConcurrentModificationException()该异常,定义变量i值为cursor,也就是0.调用外部类的get()方法,取得该位置的值,令i+1,尾指针的值赋为1,继续递归调用,每次迭代都会用 checkForComodification()方法检查一遍

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


remove()方法,移除属性,判断如果集合为空,那么抛出IllegalStateException()该异常,

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


下面也是一个内部类迭代器,ListItr,该类继承Itr实现ListIterator接口,一个带参的构造器,传入int值作为cursor, hasPrevious()方法判断如果cursor不等于0就返回ture,previous()将游标前移一位内部类里的方法还有add()set()之类不细说了,

在说AbstractList类下还有subList()方法,截取一段列表出来,很有意思,看看怎么做的,传入两个int值,这里用到RandomAcess类,提供随机访问的方法,一般情况下都是new SubList(),只有在该对象是RandomAccess类型,会new RandomAccessSubList()

public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<>(this, fromIndex, toIndex) :
new SubList<>(this, fromIndex, toIndex));
}


接着重写了equeal和hashCode方法,这里为什么要用31作为系数,为撒那么多的数字偏偏选中31,其中的奥妙耐人寻味啊。

public int hashCode() {
int hashCode = 1;
for (E e : this)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
return hashCode;
}


removeRange方法,移除指定的范围,很好理解了,就是通过for循环,一个一个的移除

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


主要的东西就这些了,当然AbstracList中还有很多其他的类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息