概述
集合是Java中比较基础的模块,所有的集合类都处于 java.util
包下,其中支持多线程的集合类位于 java.util.concurrent
包下,有兴趣的朋友可以去看看相关的源代码。
本文尝试以全局的角度,一窥Java集合框架的全貌;Java集合大致上可分 3 个部分,分别为: List
、 Set
、Map
;文章会依次介绍三者各自的作用以及区别。
话不多说,Let't Go!!!
迭代器Iterator
在开始介绍具体的容器之前,让我们先来看看迭代器为何物。迭代器提供了一种遍历容器中元素的方式,也即是说:我们可以通过迭代器来遍历集合元素。Iterator
迭代器接口定义了迭代器所应该具有的功能,具体源码如下:
public interface Iterator<E> {
/**
* 判断集合是否还有下一个元素
* @return boolean
*/
boolean hasNext();
/**
* 获取下一个元素
* @return E
*/
E next();
/**
* Java8 提供的默认方法
* 迭代的过程中不允许移除元素,会抛出操作不支持异常
* @throws UnsupportedOperationException
*/
default void remove() {
throw new UnsupportedOperationException("remove");
}
/**
* Java8 提供的默认方法
*/
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
迭代器 Iterator
接口定义了迭代器应具备的功能,其中 hasNext()
和 next()
方法由具体的容器来实现,迭代器只能通过容器本身得到,每个容器都通过内部类实现了自己的迭代器,因此迭代器的使用方式如下:
@Test
public void test(){
List<Integer> list = new ArrayList<>(6);
for (int i = 0; i < 6; i++) {
list.add(i);
}
// 迭代器只能通过容器本身得到 (PS:可能有些容器会实现一些迭代器的子接口,诸如ListIterator,只是一些优化)
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
Collection
Collection
是一个接口,它是一个高度抽象出来的接口,定义了集合的基本操作: 添加、删除、清空、遍历、是否为空、获取大小等方法。我们来看看Collection
接口的类图:
从图中我们可以看出,Collection
接口主要有 2 个子分支: List
和 Set
,并且定义了 AbstractCollection
抽象类让其他类继承,AbstractCollection
实现了 Collection
中的绝大部分方法;我们可以看出 AbstractList
和 AbstractSet
都继承于 AbstractCollection
。
其次,我们看到 Collection
接口依赖于 Iterator
接口,(依赖关系:依赖就是一个类 A 使用到了另一个类 B,因此类 B 的变化会影响到类 A。比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖。表现在代码层面,为类 B 作为参数被类 A 在某个method方法中使用。)
Collection
依赖于 Iterator
,展现在源码中是 Collection
接口定义了方法 Iterator<E> iterator()
,用以返回集合的迭代器来遍历集合。在 List
接口中,通过 listIterator()
方法返回一个 ListIterator
对象;ListIterator
接口是 List
特有的。
Collection
接口的所有子类(直接子类和间接子类)都必须实现 2 种构造函数:无参构造函数 和 参数为 Collection
的构造函数。带参数的构造函数可以用来转换 Collection
的类型。下面是 Collection
接口中定义的API(JDK1.8):
public interface Collection<E> extends Iterable<E> {
// 迭代器 每个容器都通过内部类实现了迭代器
Iterator<E> iterator();
// 添加元素
boolean add(E e);
// 批量添加元素
boolean addAll(Collection<? extends E> c);
// 移除元素
boolean remove(Object o);
// 批量删除元素
boolean removeAll(Collection<?> c);
// 是否包含元素o
boolean contains(Object o);
// 是否包含元素集
boolean containsAll(Collection<?> c);
// 保留元素
boolean retainAll(Collection<?> c);
// 获取集合长度
int size();
// 集合是否为空
boolean isEmpty();
//转换成数组
<T> T[] toArray(T[] a);
// 清空
void clear();
// equals方法
boolean equals(Object o);
// hashCode方法
int hashCode();
// java8 默认方法 转换成数组
default <T> T[] toArray(IntFunction<T[]> generator) {
return toArray(generator.apply(0));
}
// java8 提供默认方法 满足条件移除元素
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;
}
// java8 提供的默认方法
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(