4.2 Collection接口
所有通用集合实现都有一个带有Collection参数的构造函数,此构造函数(称为转换构造函数)初始化新集合以包含指定集合中的所有元素。换句话说,它允许转换集合的类型。这使得Collection接口有着非常高的通用性。
例如,有一个Collection<String> c,它可以转化成List、Set或其他类型的Collection。以下是代码示例:
Collection接口包含执行基本操作的方法,例如int size()、boolean isEmpty()、boolean contains(Object element)、boolean add(E element)、boolean remove(Object element)和Iterator<E> iterator()。
Collection接口还包含对整个集合进行操作的方法,例如boolean containsAll(Collection<?> c)、boolean addAll(Collection<? extends E> c)、boolean removeAll(Collection<?> c)、boolean retainAll(Collection<?> c)和void clear()。
Collection接口还存在用于数组操作的附加方法,例如Object[] toArray()和<T> T[] toArray(T[] a)。
在JDK 8及更高版本中,Collection接口还公开方法Stream<E> stream()和Stream<E> parallelStream(),以从底层集合中获取顺序或并行流。有关流的更多信息可以参阅第13章。
4.2.1 遍历集合
Java提供了3种遍历集合的方法:使用聚合操作、使用for-each和使用迭代器。
1.使用聚合操作
在JDK 8及更高版本中,迭代集合的首选方法是获取流并对其执行聚合操作。聚合操作通常与Lambda表达式结合使用,以使用较少的代码使编程更具表现力。以下代码按顺序遍历一组形状并打印出红色对象:
myShapesCollection.stream() .filter(e - > e.getColor()== Color.RED) .forEach(e - > System.out.println(e.getName()));
使用此API收集数据的方法有很多种。例如,可能希望将Collection的元素转换为String对象,然后将它们连接起来,用逗号分隔:
String joined = elements.stream() .map(Object::toString) .collect(Collectors.joining(", "));
或者用于统计所有员工的工资:
int total = employees.stream() .collect(Collectors.summingInt(Employee::getSalary)));
2.使用for-each
for-each允许使用for循环简明地遍历集合或数组。以下代码示例使用for-each在单独的行上打印出集合的每个元素:
3.使用迭代器
使用迭代器Iterator对象可以遍历集合并有选择地从集合中删除元素。通过调用集合的iterator方法来获得集合的Iterator。以下是Iterator接口:
如果迭代器具有更多元素,则hasNext方法返回true,并且下一个方法返回迭代中的下一个元素。remove方法从基础Collection中删除next返回的最后一个元素。每次调用next时,只调用remove方法一次,如果违反此规则就抛出异常。
比如在下面的例子中需要过滤特定的元素,则应选择使用Iterator而不是for-each:
4.2.2 集合接口批量操作
批量操作对整个集合执行操作。虽然可以使用基本操作来实现,但是在大多数情况下此类实现往往效率比较低。以下是批量操作:
· containsAll:如果目标Collection包含指定Collection中的所有元素,就返回true。
· addAll:将指定Collection中的所有元素添加到目标Collection。
· removeAll:从目标Collection中删除包含在指定Collection中的所有元素。
· retainAll:从目标Collection中删除所有未包含在指定Collection中的元素。也就是说,它仅保留目标Collection中也包含在指定Collection中的那些元素。
· clear:从集合中删除所有元素。
如果在执行操作的过程中修改了目标Collection,那么addAll、removeAll和retainAll方法会返回true。
下面是批量操作功能的一个简单示例,用于从Collection中删除指定元素的所有实例e:
c.removeAll(Collections.singleton(e));
假设要从Collection中删除所有null元素,代码如下:
Collections.singleton是一个静态工厂方法,返回一个只包含指定元素的不可变Set。