集合代表一组被称为它的元素的对象。Collection接口被用于传递所有集合最大的公共部分。例如,按照惯例,所有统一集合的实现都有一个包含一个集合参数的构造函数。这个构造函数,被称为转换构造函数,用指定集合的所有元素来构造一个新的集合,不管给定集合的子接口或者实现类型,换句话说,它允许你转换集合类型。
假设,如下例子,你有一个集合Collection<String> c,它可能是List,Set或者其它Collection类型的集合,这种方式创建一个ArrayList(List接口的一种实现类),实例化包含所有c中的元素:
List<String> list = new ArrayList<String>(c);
或者,如果你使用jdk7或更高的版本,你可以使用如下操作:
List<String> list = new ArrayList<>(c);
Collection接口包含执行基本操作的方法,如size(),isEmpty(),contains(Object element),add(E element),remove(Object element),iterator().
同时,它也包含操作整个集合的方法,如containAll(Collection
myShapesCollection.stream().filter(e->e.getColor()==Color.RED).forEach(e->System.out.println(e.getName()));
同理,你也可以请求一个平行流,当这个集合很大并且你的计算机有足够的内核时将更加有意义。
myShapesCollection.parallelStream().filter(e->e.getColor()==Color.RED).forEach(e->System.out.println(e.getName));
计算所有员工的工资:
int total = employees.stream().collect(Collectors.summingInt(Employee::getSalary));
String joined = elements.stream().map(Object::toString).collect(Collectors.joining(","));
这些例子中,你可以处理流和聚合操作。
集合框架总是提供提供一些所谓的大容量操作方法作为它的API的一部分。这些包括操作整个集合的方法,如containsAll,addAll,removeAll等等。不要因为聚合操作和存在的大容量操作而发生困惑,这种大量操作在旧版本中是不可变的,意味着他们所有修改了底层的集合。 相反,新集合操作不会修改底层集合。当使用新聚合操作和lambda表达式时,你必须小心以免变化,以致不会在将来产生问题,你的代码未来可能在平行流中运行。
for-each构造
for-each构造允许你简单循环的遍历一个集合或者数组。以下代码使用for-each构造来打印一个集合中的元素:
for(Object o : collection){
System.out.println(o);
}
迭代器(Iterators)
一个迭代器是一个对象,它是你能够遍历一个集合并有选择的删除元素,如果你希望这样做的话。你通过调用Collection的iterator方法获取一个迭代器。以下代码是迭代器接口。
public interface Iterator<E>{
boolean hasNext();
E next();
void remove();
}
hasNext方法,当这个迭代器还有元素时,会返回true,next方法返回迭代器中的下一个元素,remove方法删除最后一个元素,这个元素可以通过next方法返回。remove方法可能只有一次被调用,在每次调用next之后,如果违反了规则则会抛出一个异常。
注意,Iterator.remove是唯一一个在使用迭代器修改集合时的安全方式;
使用Iterator替代for-each构造:
- 删除当前元素,for-each构造隐藏了迭代器,所以你不能调用remove,因此,for-each构造不能用于过滤
- 在多集合中并行迭代
以下方法将展示怎么使用迭代器来过滤一个任意的集合,遍历集合删除指定的元素。
static void filter(Collection<?> c){
for(Iterator<?> it = c.iterator();it.hasNext();)
if(!cond(it.next()))
it.remove;
}
这段代码是通用的,意味着适合于任何Collection的实现类,这个例子演示了使用java集合框架来写多态算法是多么的简单。
集合接口批量操作(Collection interface bulk operations)
批量操作对整个集合的一个操作,使用基本操作来实现这些简短操作:
- containsAll — 如果目标集合包含所有给定集合的元素,则返回true
- addAll — 将给定集合中的所有元素添加到目标集合中
- removeAll — 从目标集合中删除所有包含给定集合中的元素
- retainAll — 删除目标集合中不在给定集合中元素的所有元素,即,它保留目标集合中元素出现在给定集合中元素的元素。
- 清空 — 删除集合中所有的元素
方法addAll,removeAll,retainAll操作,如果目标集合在执行操作过程被修改,那么将返回true
一个展示批量操作功能的例子
c.removeAll(Collections.singleton(e));
删除所有null元素
c.removeAll(Collections.singleton(null));
集合接口的数组操作(Collection Interface Array Operations)
toArray方法作为在集合和希望以数组形式输出的旧APIs中的一座桥梁,数组操作允许将集合的内容转换为数组,使用没有参数的的简单形式创建一个新对象数组,更加复杂的形式允许调用者提供一个数组或者选择运行时指定输出数组类型。
Object[] a = c.toArray();