Collection表示一组对象,称作元素。Collection接口被用作传递对象的接口,需要最大的通用性。例如,按约定通用接口的实现有一个构造器,它获取一个Collection参数。这个构造器叫做conversion constructor,初始化一个新的接口来保存指定接口的所有参数,无论给定的子接口或者实现类型是什么。换句话说,它允许你转换接口的类型。
例如,假如有一个Collection<String> c
,可能是一个List或者Set,或者其他的集合。这种形式创建了一个新的ArrayList(List接口的实现),最初在c中保存所有的元素。
List<String> list = new ArrayList<String>(c); 或者-如果使用JDK7或者以后的-你可以使用这金刚钻操作List<String> list = new ArrayList<>(c); Collection接口包括了执行基本操作的方法,像int size()
,boolean isEmpty()
,boolean contains(Object element)
,boolean add(E element)
,boolean remove(Object element)
,和Iterator<E> iterator()
. 它也包括了操作更个集合的方法,boolean containsAll(Collection<?> c)
,boolean addAll(Collection<? extends E> c)
,boolean removeAll(Collection<?> c)
,boolean retainAll(Collection<?> c)
,和void clear()
. 额外的数据操作方法(比如Object[] toArray()
和<T> T[] toArray(T[] a)
)也存在。 在JDK8和后来的版本中,Collection接口也公开了Stream<E> stream()
和Stream<E> parallelStream()
,从指定集合中获取连续或者平行流。 Collection接口做了你所期望的,在给定的代表一组对象的集合。它有告诉你集合中有多少元素的方法(size,isEmpty()),检查一个给定的对象是否在集合中(contains), 在集合中添加或者移除的方法(add,remove),迭代集合的方法(iterator)。 add方法被定义成普通的足够了这样对于允许重复的集合还有不允许的集合。它将保证在add调用后,Collection将保有指定的元素并返回true,如果集合改变了作为调用的结果。 相似的,remove方法被定义为从一个集合中移除一个指定元素的单一实例,以假定集合中存在这样的元素开始,结果集合被修改了,就返回true。Traversing Collections 遍历集合
有三种遍历集合的方式:1 使用集合操作 2 使用for-each构见 3 使用iterators
Aggregate Operations集合操作
在JDK8h和后面的,迭代一个集合的首选方法是获取集合的流并执行集合操作。集合操作通常用于匿名函数表示式的结合使程序更具有表现力,使用更少的代码。
下面的代码持续迭代一个shape的集合并输出红色对象:
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())); 有许多不同的方式用这个API采集数据。例如,你可能想将Collection元素转换为String对象,稍后假如它们,通过逗号隔开。String joined = elements.stream() .map(Object::toString) .collect(Collectors.joining(", ")); 或者统计员工的工资:int total = employees.stream() .collect(Collectors.summingInt(Employee::getSalary))); 这些仅仅是使用流和集合操作你能做的很少的例子。 集合框架总是提供了大量的所谓的“bulk operations”作为API的部分。这些包括在整个集合上操作的方法,像containsAll
,addAll
,removeAll
等等。不要与JDK8中介绍的 集合操作方法混淆。在新的聚集方法和以存在的“bulk operations”的方法的关键区别是老版本的是可变的,意味着它们全部修改了指定的集合。相比之下,新的聚集操作 不修改指定的集合。当使用新的聚集操作和隐匿函数表达式,你必须注意避免变种不至于在将来产生问题,你的代码将从稍后的平行流中运行。for-each Construct
for-each构件允许你方便的使用一个for循环转换一个集合或者数组。下面的代码使用for-each构件,换行输出集合的每个元素。
for (Object o : collection) System.out.println(o);Iterators
Iterators
IteratorsIterator是一个对象,能使你转换一个集合并有选择的从集合中移除元素。如果愿意,你为集合获取一个Iterator通过调用它的iterators方法。下面的是Iterator接口。
public interface Iterator<E> { boolean hasNext(); E next(); void remove(); //optional } 如果迭代中有更多的元素,hasNext返回true,而next方法返回迭代的下一个元素。remove方法移除从指定集合中通过next返回的最后一个元素。每次调用next,remove方法可能 仅仅调用一次。如果违反了规则,将抛出异常。 注意Iterator.remove是唯一安全的方式修改迭代中的集合。表现是未知的,如果指定的集合在其他方式下被修改,当迭代在处理的时候。 使用Iterator替换for-wach构件 你需要做的是: 移除当前元素。for-each构件隐藏了iterator,这样你不能调用remove。因此,for-each构件不能过滤。 在平行流中迭代多集合 下面的方法显示了如何使用Iterator过滤一个任意的集合。即遍历集合移除指定的元素。static void filter(Collection<?> c) { for (Iterator<?> it = c.iterator(); it.hasNext(); ) if (!cond(it.next())) it.remove(); }简答的代码是多态的,意味着可以为任何集合工作而不是实现。这个例子演示了使用Java集合框架写一个多态算法。Collection Interface Bulk Operations
散装操作在一个全部的Collection上执行了一个操作。你可以实现这些简写操作使用基本的操作,虽然大多数情况这些的实现效率低下。下面是bulk operations:
containsAll
-- 返回true 如果目标集合包含了指定集合的所有元素。
addAll
-- 将指定集合的所有元素添加到目标集合中
removeAll
-- 从目标集合中移除所有元素也包括在指定集合中包含的元素
retainAll
-- 从目标集合中移除所有元素但不包括指定集合中包含的元素。即它仅保留在目标集合和指定集合中的元素
clear
-- 从集合中移除所有元素addAll
,removeAll
,和retainAll
返回true 如果目标集合被修改了 在执行操作的过程中。
作为一个散装操作强大的简单例子,考虑下面的形式移除指定元素e所有的实例,从集合c。c.removeAll(Collections.singleton(e));更特殊的,你可以从集合中移除所有null的元素:c.removeAll(Collections.singleton(null)); 这种形式的使用Collections.singleton,是一个静态工厂方法返回一个不可变Set仅仅包含了指定的元素。Collection Interface Array Operations
toArray方法被提供作为集合和旧的APIs的桥梁,期望以数组输出。数组操作允许Collection的内容被翻译到数组中。无参的简单形式创建了一个new的对象数组。更复杂的形式 允许调用者提供一个数组或者选择输出数组的运行类型。 例如,假设c是一个Collection。下面的代码片段倾倒c的内容到一个最新的下拨的对象数组,其长度由c中的元素个数指定。Object[] a = c.toArray();假设c只包含字符串(也许c是Collection<String>
类型),下面的代码片段倾倒c的内容到一个最新下拨的String数组中,其长度由c中的元素个数指定。String[] a = c.toArray(new String[0]);