前言
标题取得有点大,一口气分析三块的源码,看上去是个很大的话题,不过在个人看来,一方面,这三个都是接口,不涉及代码实现,读起来比较快,另一方面,大家都知道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。