(一)jdk源码分析之collection,List,Set

前言

标题取得有点大,一口气分析三块的源码,看上去是个很大的话题,不过在个人看来,一方面,这三个都是接口,不涉及代码实现,读起来比较快,另一方面,大家都知道List,Set这两个接口都继承自collection,他们之间存在关联,所以放在一块分析讨论最能凸显,这三块接口的区别和特色。

Collection

public interface Collection<E> extends Iterable<E>{

int size();

 boolean isEmpty();

Iterator<E> iterator();

Object[] toArray();

 <T> T[] toArray(T[] a);

boolean add(E e);

boolean remove(Object o);

boolean containsAll(Collection<?> c);

boolean addAll(Collection<? extends E> c);

//方法未列全

}

我们首先看到Collection接口继承了Iterable,返回迭代器的方法Collection要有。然后对于集合类公有的操作,包括返回一个集合内对象的数组,添加,删除元素,检查指定元素是否存在等方法,也必须要由。

在我的理解中,Collection接口实际上是对java集合类的特性的高度抽象,一个集合类,它至少要拥有对元素,这是所有集合类的共性。而Set和List接口作为Collection接口的继承,除了Collection本身的东西之外,还必须要有些针对自己类型特化出来的方法。

List

List接口相对于Collection一定要有一些自己的东西,那么有哪些东西是属于他自己的呢

public interface List<E> extends Collection<E> {

   @SuppressWarnings({"unchecked", "rawtypes"})  //禁止显示警报的注解
    default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }

 E get(int index);

E set(int index, E element);

void add(int index, E element);

E remove(int index);

ListIterator<E> listIterator();

ListIterator<E> listIterator(int index);

 List<E> subList(int fromIndex, int toIndex);

}

在这里我们可以看到,List相较于Collection,主要是多了可以根据下标去访问修改指定元素,以及排序的方法,这里就凸显出了List接口和Collection接口的不同之处,作为List,相较于高度抽象的集合类,它的特点是有序的,所以对于List这种集合而言,它应该可以被排序,以及能够被下标访问。

还有很有趣的一点,我们发现List接口还要求他的实现能够返回一种特殊的迭代器listIterator();,这种迭代器有什么特别的呢。我们去查看一下listIterator的源码。

public interface ListIterator<E> extends Iterator<E> {

    boolean hasNext(); 
    E next();
    boolean hasPrevious();
    E previous();
    int nextIndex();
    int previousIndex();
    void remove();
    void set(E e);
    void add(E e);
}

这个接口的方法有哪些特别之处呢,我们对比一下Iterator的接口,很快就能够显现出来了。

public interface Iterator<E> {

boolean hasNext();

 E next();

 default void remove() {
        throw new UnsupportedOperationException("remove");
    }

default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }

}

看来listiterator方法比Iterator还是要多上不少的,主要多了哪些方法呢?我们看到,listiterator不但能通过next()向下访问,还能够通过previous向上访问,也可以再迭代器访问到的点进行插入,取代,删除,以及知道自己所迭代到的下标位置。

所以由此我们不难发现,listiterator相较于iterator,还是主要针对List有序这一点添加了一些方法,这个迭代器相较于普通的迭代器功能更加强大,不但可以有序地向上向下遍历,甚至还可以通过迭代器去操作List本身,可以说是非常牛逼了。

最后,我们发现List还有一个叫subList()的方法,这个方法是干什么的呢。阅读注解后我知道了他会根据你传入的下标返还List的一个子集,但返还的到底是怎样的子集肯定还是要看具体实现,在此不谈。

Set

终于轮到了Set的源码,Set接口和前两者又有什么区别呢

public interface Set<E> extends Collection<E> {

 int size();

 boolean isEmpty();

boolean contains(Object o);

Iterator<E> iterator();

Object[] toArray();

 <T> T[] toArray(T[] a);

 boolean add(E e);

 boolean containsAll(Collection<?> c);

boolean addAll(Collection<? extends E> c);

 boolean retainAll(Collection<?> c);

boolean removeAll(Collection<?> c);

 void clear();

 boolean equals(Object o);

int hashCode();

}

好像和collection没啥区别……不过Set本身好像确实和集合,不能出现重复元素的特性应该也是在实现类中,也不存在什么基于自己特性的新方法,over。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值