The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
A Collection
represents a group of objects known as its elements. Collection
表示一组称为其元素的对象。The Collection
interface is used to pass around collections of objects where maximum generality is desired. Collection
接口用于传递需要最大通用性的对象集合。For example, by convention all general-purpose collection implementations have a constructor that takes a 例如,按照惯例,所有通用集合实现都有一个接受Collection
argument. Collection
参数的构造函数。This constructor, known as a conversion constructor, initializes the new collection to contain all of the elements in the specified collection, whatever the given collection's subinterface or implementation type. 这个构造函数称为转换构造函数,它初始化新集合以包含指定集合中的所有元素,无论给定集合的子接口或实现类型如何。In other words, it allows you to convert the collection's type.换句话说,它允许您转换集合的类型。
Suppose, for example, that you have a 例如,假设您有一个Collection<String> c
, which may be a List
, a Set
, or another kind of Collection
. Collection<String> c
,它可以是List
、Set
或其他类型的Collection
。This idiom creates a new 这个习惯用法创建了一个新的ArrayList
(an implementation of the List
interface), initially containing all the elements in c
.ArrayList
(List
接口的实现),最初包含c
中的所有元素。
List<String> list = new ArrayList<String>(c);
List<String> list = new ArrayList<>(c);
The Collection
interface contains methods that perform basic operations, such as int size()
, boolean isEmpty()
, boolean contains(Object element)
, boolean add(E element)
, boolean remove(Object element)
, and Iterator<E> iterator()
.Collection
接口包含执行基本操作的方法,例如int size()
、boolean isEmpty()
、boolean contains(Object element)
、boolean add(E element)
、boolean remove(Object element)
和Iterator<E> iterator()
。
It also contains methods that operate on entire collections, such as 它还包含对整个集合进行操作的方法,例如boolean containsAll(Collection<?> c)
, boolean addAll(Collection<? extends E> c)
, boolean removeAll(Collection<?> c)
, boolean retainAll(Collection<?> c)
, and void clear()
.boolean containsAll(Collection<?> c)
、boolean addAll(Collection<? extends E> c)
、boolean removeAll(Collection<?> c)
、boolean retainAll(Collection<?> c)
和void clear()
。
Additional methods for array operations (such as 数组操作的其他方法(例如Object[] toArray()
and <T> T[] toArray(T[] a)
exist as well.Object[] toArray()
和<T> T[] toArray(T[] a)
)也存在。
In JDK 8 and later, the 在JDK 8及更高版本中,Collection
interface also exposes methods Stream<E> stream()
and Stream<E> parallelStream()
, for obtaining sequential or parallel streams from the underlying collection. Collection
接口还公开了Stream<E> stream()
和Stream<E> parallelStream()
方法,用于从底层集合获取顺序或并行流。(See the lesson entitled Aggregate Operations for more information about using streams.)(有关使用流的更多信息,请参阅题为“聚合操作”的课程。)
The 如果Collection
interface does about what you'd expect given that a Collection
represents a group of objects. Collection
代表一组对象,那么Collection
接口可以实现预期的功能。It has methods that tell you how many elements are in the collection (它有一些方法可以告诉您集合中有多少个元素(size
, isEmpty
), methods that check whether a given object is in the collection (contains
), methods that add and remove an element from the collection (add
, remove
), and methods that provide an iterator over the collection (iterator
).size
,isEmpty
),检查给定对象是否在集合中的方法(contains
),从集合中添加和删除元素的方法(add
、remove
),以及在集合中提供迭代器的方法(iterator
)。
The add
method is defined generally enough so that it makes sense for collections that allow duplicates as well as those that don't. add
方法的定义非常笼统,因此对于允许重复的集合和不允许重复的集合都有意义。It guarantees that the 它保证调用完成后Collection
will contain the specified element after the call completes, and returns true
if the Collection
changes as a result of the call. true
将包含指定的元素,如果调用导致true
更改,则返回true
。Similarly, the 类似地,remove
method is designed to remove a single instance of the specified element from the Collection
, assuming that it contains the element to start with, and to return true
if the Collection
was modified as a result. remove
方法被设计为从Collection
中移除指定元素的单个实例,假设它包含要开始的元素,并且如果因此修改了Collection
,则返回true
。
There are three ways to traverse collections: (1) using aggregate operations (2) with the 遍历集合有三种方法:(1)使用聚合操作(2)使用for-each
construct and (3) by using Iterator
s. for-each
构造和(3)使用Iterator
。
In JDK 8 and later, the preferred method of iterating over a collection is to obtain a stream and perform aggregate operations on it. 在JDK 8及更高版本中,迭代集合的首选方法是获取流并对其执行聚合操作。Aggregate operations are often used in conjunction with lambda expressions to make programming more expressive, using less lines of code. 聚合操作通常与lambda表达式结合使用,以使编程更具表现力,使用更少的代码行。The following code sequentially iterates through a collection of shapes and prints out the red objects:以下代码按顺序遍历一组形状并打印出红色对象:
myShapesCollection.stream() .filter(e -> e.getColor() == Color.RED) .forEach(e -> System.out.println(e.getName()));
Likewise, you could easily request a parallel stream, which might make sense if the collection is large enough and your computer has enough cores:同样,您可以轻松地请求并行流,如果集合足够大并且您的计算机有足够的内核,这可能是有意义的:
myShapesCollection.parallelStream() .filter(e -> e.getColor() == Color.RED) .forEach(e -> System.out.println(e.getName()));
There are many different ways to collect data with this API. 使用此API收集数据有许多不同的方法。For example, you might want to convert the elements of a 例如,您可能希望将Collection
to String
objects, then join them, separated by commas:Collection
的元素转换为String
对象,然后连接它们,并用逗号分隔:
String joined = elements.stream() .map(Object::toString) .collect(Collectors.joining(", "));
Or perhaps sum the salaries of all employees:或者将所有员工的工资相加:
int total = employees.stream() .collect(Collectors.summingInt(Employee::getSalary)));
These are but a few examples of what you can do with streams and aggregate operations. 这些只是您可以使用流和聚合操作的几个示例。For more information and examples, see the lesson entitled Aggregate Operations.有关更多信息和示例,请参阅题为聚合操作的课程。
The Collections framework has always provided a number of so-called "bulk operations" as part of its API. Collections框架始终提供许多所谓的“批量操作”作为其API的一部分。These include methods that operate on entire collections, such as 这些方法包括对整个集合进行操作的方法,例如containsAll
, addAll
, removeAll
, etc. containsAll
、addAll
、removeAll
等。Do not confuse those methods with the aggregate operations that were introduced in JDK 8. 不要将这些方法与JDK 8中引入的聚合操作混淆。The key difference between the new aggregate operations and the existing bulk operations (新的聚合操作和现有的批量操作(containsAll
, addAll
, etc.) is that the old versions are all mutative, meaning that they all modify the underlying collection. containsAll
、addAll
等)之间的关键区别在于,旧版本都是变异的,这意味着它们都修改了基础集合。In contrast, the new aggregate operations do not modify the underlying collection. 相反,新的聚合操作不会修改基础集合。When using the new aggregate operations and lambda expressions, you must take care to avoid mutation so as not to introduce problems in the future, should your code be run later from a parallel stream.在使用新的聚合操作和lambda表达式时,必须注意避免变异,以免在以后从并行流运行代码时引入问题。
The for-each
construct allows you to concisely traverse a collection or array using a for
loop see The for Statement. for-each
构造允许您使用for
循环简洁地遍历集合或数组;请参阅for语句。The following code uses the 下面的代码使用for-each
construct to print out each element of a collection on a separate line.for-each
构造在单独的一行上打印出集合的每个元素。
for (Object o : collection) System.out.println(o);
An Iterator
is an object that enables you to traverse through a collection and to remove elements from the collection selectively, if desired. Iterator
是一个对象,它使您能够遍历集合,并在需要时有选择地从集合中删除元素。You get an 通过调用集合的Iterator
for a collection by calling its iterator
method. iterator
方法,可以获得集合的Iterator
。The following is the 下面是Iterator
interface.Iterator
接口。
public interface Iterator<E> { boolean hasNext(); E next(); void remove(); //optional }
The 如果迭代有更多元素,hasNext
method returns true
if the iteration has more elements, and the next
method returns the next element in the iteration. hasNext
方法将返回true
,而next
方法将返回迭代中的下一个元素。The remove
method removes the last element that was returned by next
from the underlying Collection
. remove
方法从基础Collection
中移除next
返回的最后一个元素。The 每次调用remove
method may be called only once per call to next
and throws an exception if this rule is violated.next
时,remove
方法只能调用一次,如果违反此规则,将抛出异常。
Note that 请注意,Iterator.remove
is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.Iterator.remove
是在迭代过程中修改集合的唯一安全方法;如果在迭代过程中以任何其他方式修改了基础集合,则该行为未指定。
Use 需要时,请使用Iterator
instead of the for-each
construct when you need to:Iterator
,而不是for-each
构造:
for-each
construct hides the iterator, so you cannot call remove
. for-each
构造隐藏了迭代器,因此不能调用remove
。for-each
construct is not usable for filtering.for-each
构造不可用于筛选。The following method shows you how to use an 下面的方法展示了如何使用Iterator
to filter an arbitrary Collection
that is, traverse the collection removing specific elements.Iterator
筛选任意Collection
#151;也就是说,遍历集合以移除特定元素。
static void filter(Collection<?> c) { for (Iterator<?> it = c.iterator(); it.hasNext(); ) if (!cond(it.next())) it.remove(); }
This simple piece of code is polymorphic, which means that it works for any 这段简单的代码是多态的,这意味着无论实现如何,它都适用于任何Collection
regardless of implementation. Collection
。This example demonstrates how easy it is to write a polymorphic algorithm using the Java Collections Framework.这个例子演示了使用Java集合框架编写多态算法是多么容易。
Bulk operations perform an operation on an entire 批量操作对整个Collection
. Collection
执行操作。You could implement these shorthand operations using the basic operations, though in most cases such implementations would be less efficient. The following are the bulk operations:
containsAll
returns true
if the target Collection
contains all of the elements in the specified Collection
.addAll
adds all of the elements in the specified Collection
to the target Collection
.removeAll
removes from the target Collection
all of its elements that are also contained in the specified Collection
.retainAll
removes from the target Collection
all its elements that are not also contained in the specified Collection
. That is, it retains only those elements in the target Collection
that are also contained in the specified Collection
.clear
removes all elements from the Collection
.The addAll
, removeAll
, and retainAll
methods all return true
if the target Collection
was modified in the process of executing the operation.
As a simple example of the power of bulk operations, consider the following idiom to remove all instances of a specified element, e
, from a Collection
, c
.
c.removeAll(Collections.singleton(e));
More specifically, suppose you want to remove all of the null
elements from a Collection
.
c.removeAll(Collections.singleton(null));
This idiom uses Collections.singleton
, which is a static factory method that returns an immutable Set
containing only the specified element.
The toArray
methods are provided as a bridge between collections and older APIs that expect arrays on input. The array operations allow the contents of a Collection
to be translated into an array. The simple form with no arguments creates a new array of Object
. The more complex form allows the caller to provide an array or to choose the runtime type of the output array.
For example, suppose that c
is a Collection
. The following snippet dumps the contents of c
into a newly allocated array of Object
whose length is identical to the number of elements in c
.
Object[] a = c.toArray();
Suppose that c
is known to contain only strings (perhaps because c
is of type Collection<String>
). The following snippet dumps the contents of c
into a newly allocated array of String
whose length is identical to the number of elements in c
.
String[] a = c.toArray(new String[0]);