Collection
是在前文中已经介绍过了,他是两种集合类型之一的父接口,首先我们来看一下它的框架结构
框架图
可以看出,作为顶级的框架,Collection
仅仅是继承了Iterable
接口,接下来,我们来看一下Iterable
的源码,看看有什么收获。
public interface Iterable<T> {
Iterator<T> iterator();
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
可以看到这个接口中有三个方法,其中iterator()
方法可以给我们提供一个迭代器,这个在之前的教程就已经说过了,而forEach()
方法提供了一个函数式接口的参数,我们可以使用lambda
表达式结合来使用:
Collection<String> collection = ...;
collection.forEach(String s -> System.out.println(s));
这样就可以获取到每个值,它的底层实现是加强for
循环,实际上也是迭代器去遍历,因为编译器会把加强for
循环编译为迭代遍历。
Spliterator()
是1.8
新加的方法,字面意思可分割的迭代器,不同以往的iterator()
需要顺序迭代,Spliterator()
可以分割为若干个小的迭代器进行并行操作,既可以实现多线程操作提高效率,又可以避免普通迭代器的fail-fast
(fail-fast
机制是java
集合中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast
事件)机制所带来的异常。Spliterator()
可以配合1.8
新加的Stream()
进行并行流的实现,大大提高处理效率。具体的使用方法会在讲解Stream()
的时候进行讲解。
Collection源码
接下来,我们来看一下Collection的源码,
public interface Collection<E> extends Iterable<E> {
//1
int size();
//2
boolean isEmpty();
//3
boolean contains(Object o);
//4
Iterator<E> iterator();
//5
Object[] toArray();
//6
<T> T[] toArray(T[] a);
//7
boolean add(E e);
//8
boolean remove(Object o);
//9
boolean containsAll(Collection<?> c);
//10
boolean addAll(Collection<? extends E> c);
//11
boolean removeAll(Collection<?> c);
//12
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
//13
boolean retainAll(Collection<?> c);
//14
void clear();
//15
boolean equals(Object o);
//16
int hashCode();
//17
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
//18
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
//19
default Stream<E> `parallelStream`() {
return StreamSupport.stream(spliterator(), true);
}
}
可以看到,Collection()
中提供了19个接口方法。接下来,我们来了解一下这些方法的作用:
size()
,返回当前存储在集合中的元素个数。isEmpty()
,如果集合中没有元素,返回true。contains(Object obj)
,如果集合中包含了一个与obj相等的对象,返回true。iterator()
,返回这个集合的迭代器。toArray()
,返回这个集合的对象数组toArray(T[] arrayToFill)
,返回这个集合的对象数组,如果arrayToFill足够大,就将集合中的元素填入这个数组中。剩余空间填补null;否则,分配一个新数组,其成员类型与arrayToFill的成员类型相同,其长度等于集合的大小,并填充集合元素。add(Object element)
,将一个元素添加到集合中,如果由于这个调用改变了集合,返回true。remove(Object obj)
,从集合中删除等于obj的对象,如果有匹配的对象被删除,返回true。containsAll(Collection<?> other)
,如果这个集合包含other集合中的所有元素,返回true。addAll(Collection<? extends E> other)
,将other集合中的所有元素添加到这个集合,如果由于这个调用改变了集合,返回true。removeAll(Collection<?> other)
,从这个集合中删除other集合中存在的所有元素。如果由于这个调用改变了集合,返回true。removeIf(Predicate<? super E> filter)
,从这个集合删除filter返回true的所有元素,如果由于这个调用改变了集合,则返回true。retainAll(Collection<?> other)
,从这个集合中删除所有与other集合中的元素不同的元素。如果由于这个调用改变了集合,返回true。clear()
,从这个集合中删除所有的元素。equals(Object o)
,如果两个集合对象相等返回true。hashCode()
,返回该集合对象的哈希值。spliterator()
,返回分割后的若干个小的迭代器。stream()
,返回这个集合对于的流对象。parallelStream()
,返回这个集合的并行流对象。
可以看到,作为第一级的集合接口,Collection
提供了一些基础操作(增,删),并且可以通过实现Iterable
接口获取一个迭代器去遍历获取集合中的元素。
下节预告
下节我们来讲AbstractCollction
这个类,作为Collection的第一级子类,它又给我们提供了什么作用呢?