集合框架专题2—AbstractList

AbstractList      

         前言: 本文所采用的jdk版本为:jdk1.8.0_111。 

        

        上图可以看出,AbstractList继承自AbstractCollection,并且实现了List接口,其子类中也包含着很多常用的List实现类,如ArrayList、LinkedList等。上一篇文章我们知道,AbstractCollection实现了除iterator 和size 以外的所有方法,那我们这一篇来看一下AbstractList中又实现了哪些方法。



        上图是在eclipse中截的图,是AbstractList中所有的成员,我们可以看到除了常见的一些方法,其中还包含的内部迭代器类等。

一、实现的方法

1.1 add(E e)

    public boolean add(E e) {
        add(size(), e);
        return true;
    }
        AbstractList中实现了add方法,该源码中可以看出,它调用了add(size(),e)方法,该方法是在List接口中定义的,用于list中向指定下标插入元素,这里该方法的意思自然是向列表末尾插入一个元素。


1.2 该类中默认不支持的方法

    abstract public E get(int index);

    public E set(int index, E element) {
        throw new UnsupportedOperationException();
    }

    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    public E remove(int index) {
        throw new UnsupportedOperationException();
    }
        上面4个方法中,我们又见到了熟悉的情况,本类中以上四个方法都不支持,但是第一个写成抽象方法,下面三个皆默认抛出异常,这种写法上篇文章提到过。


1.3 indexOf(Object o)

    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;
    }
        这是一个索引方法,查找元素第一次出现的位置,源码中的迭代器要着重看一下,因为这里使用的是ListIterator迭代器,关于Iterator和ListIterator的区别,后面会单独写一篇文章来分析,这里仅用到的是ListIterator特有的一种功能,就是定位当前索引位置的功能,这是Iterator所没有的功能。


1.4 lastIndexOf(Object o)

    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;
    }
        这个方法的功能是返回元素的最后一次出现的位置,这里运用的ListIterator的另一个功能——倒序迭代,这里采用倒序的形式,查找出的元素即是整体最后一次出现的位置。


1.5 clear()

    public void clear() {
        removeRange(0, size());
    }
    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();
        }
    }

        这里重写了clear()方法,实际上不重写功能也可以实现,只是这里采用了ListIterator重新实现了功能,并且这里引出一个removeRange方法,源码中可以看出该方法可以自定义删除的开始和结束索引值,并在索引值内进行迭代删除元素。


1.6 addAll(int index, Collection<? extends E> c)

    public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index); //检查index是否合法,如果不合法,会报一个数组越界的错误的异常。
        boolean modified = false;
        for (E e : c) {
            add(index++, e);
            modified = true;
        }
        return modified;
    }
        将c的元素全部添加到集合中的指定位置。


1.7 迭代器

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

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

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

        return new ListItr(index);
    }

        这三个方法实现了迭代器的定义,可以看出实际上list中是同时支持这两种迭代器的,并且,ListIterator 支持任意位置的索引。


1.8 subList(int fromIndex, int toIndex)

    public List<E> subList(int fromIndex, int toIndex) {
        return (this instanceof RandomAccess ?
                new RandomAccessSubList<>(this, fromIndex, toIndex) :
                new SubList<>(this, fromIndex, toIndex));
    }
        该方法是用于返回指定索引值之间的list的映射,这里之所以指出是映射,是因为它得到的list并不是新的实例,而是在原来的基础上映射出来的,其所指向的内存还在原list上,所以注意,新的list如果修改的话,会影响原来的list的元素。故该方法慎用。


1.9 equals(Object o)

    public 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()) {
            E o1 = e1.next();
            Object o2 = e2.next();
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }
        return !(e1.hasNext() || e2.hasNext());
    }
        这里重写了equals方法,从源码上分析可知,要使equals为true,要么其“==”相同,即同一个实例,要么就是他们中的每一个元素相同(要么同为null,要么元素的equals为true),此时equals方法才能为true。















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值