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

深入了解下AbstractList这个抽象类,该类继承AbstractCollect实现List接口,

  1. 先看下类下有哪些东西,基本上都是实现父级的方法
    这里写图片描述
    它有两个私有的内部类如下
    这里写图片描述
  2. 方法概要
    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是要插入的位置, 调用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中还有很多其他的类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值