了解集合层次结构
避免在集合层次结构中迷路
集合框架分为多个接口和类的层次结构。您需要理解的第一个层次结构如下:集合接口层次结构。
请注意,一些接口已被省略,您将在后面看到它们。
Iterable 接口
此层次结构的第一个接口是 Iterable
接口,实际上它不属于集合框架。在这里提一下它仍然很有价值,因为它 是 Collection
接口的超接口,因此也是此层次结构中所有接口的超接口。
The Iterable
接口是 Java SE 5 (2004) 的新增内容。实现 Iterable
的对象是可以迭代的对象。它是在 Java SE 5 中与for each 代码模式一起添加的。
您可能已经熟悉这种迭代 Collection
元素的方法。
Collection<String> collection = ...;
for (String element: collection) {
// do someting with element
}
您可能已经知道可以使用此模式或任何数组迭代任何集合。事实证明,实际上任何 Iterable
实例都可以在此处使用。
实现 Iterable
接口非常容易:您只需提供另一个接口的实例,Iterator
,您将在下面看到它。
使用 Collection 接口在容器中存储元素
所有其他接口都与在容器中存储元素有关。
两个接口 List
和 Set
都具有共同的行为,这些行为由 Collection
接口建模。The Collection
接口对元素容器建模了多个操作。在不深入技术细节的情况下(暂时!),以下是可以使用 Collection
执行的操作:
- 添加或删除元素;
- 测试给定元素的存在;
- 询问包含的元素数量,或此集合是否为空;
- 清除此内容。
由于 Collection
是元素的集合,因此在 Collection
接口上也定义了集合操作:
- 测试一个集合是否包含在另一个集合中;
- 并集;
- 交集;
- 补集。
最后,Collection
接口还对访问其元素的不同方式进行建模:
- 您可以通过使用迭代器迭代集合的元素;
- 您可以对这些元素创建流,这些流可以是并行的。
当然,所有这些操作在 List
和 Set
上也可用。那么,普通 Collection
实例与 Set
实例或 List
实例之间有什么区别?
使用 List 扩展 Collection
元素 List
与元素 Collection
之间的区别在于,List
会记住元素添加的顺序。
第一个结果是,如果您迭代列表的元素,您将获得的第一个元素是第一个添加的元素。然后您将获得第二个元素,依此类推,直到所有元素都被看到。因此,您迭代元素的顺序始终相同,它由这些元素添加的顺序固定。对于普通 Collection
或 Set
,您没有这种保证。
事实证明,集合框架提供的
Set
的某些实现恰好始终以相同的顺序迭代元素。这是一个意外的效果,您的代码不应依赖此行为。
还有一个第二个结果,可能不像第一个结果那么明显,即列表的元素具有索引。查询集合的第一个元素没有意义。查询列表的第一个元素是有意义的,因为列表确实会记住这一点。
这些索引是如何处理的?好吧,再一次,这是实现的责任。接口的第一个作用是指定行为,而不是告诉实现应该如何实现该行为。
正如您将看到的那样,List
接口在 Collection
接口中添加了新的操作。由于列表的元素具有索引,因此您可以使用该索引执行以下操作。
- 获取特定索引处的元素,或删除它
- 在特定位置插入元素或替换元素
- 获取两个索引之间的元素范围。
使用 Set 扩展 Collection
元素 Set
与元素 Collection
之间的区别在于,您不能在 Set
中拥有重复项。您可以在 Collection
中拥有多个相同类的实例,这些实例是相等的,甚至可以拥有同一个实例多次。这在 Set
中是不允许的。如何强制执行这是实现的责任,您将在本教程的后面看到这一点。
这种行为的结果之一是,将元素添加到 Set
中可能会失败。
然后您可能会问自己:我可以拥有一个容器来防止重复,并且在其中元素具有索引吗?答案并不简单。集合框架为您提供了一个 Set
实现,使用它您将始终以相同的顺序迭代元素,但这些元素没有索引,因此此类不实现 List
。
这种行为上的差异不会在 Set
接口中带来任何新的操作。
使用 SortedSet 和 NavigableSet 对 Set 的元素进行排序
The Set
接口本身有两个扩展:SortedSet
和 NavigableSet
.
The SortedSet
接口按升序维护其元素。再一次,如何强制执行这是实现的责任,正如您将在后面看到的那样。
为了能够对它们进行排序,SortedSet
需要比较您的元素。它如何实现这一点?好吧,Java 语言中定义了两种标准机制来实现这一点。
- 您的元素可以实现
Comparable
接口,并提供compareTo()
方法。 - 您可以向
SortedSet
提供一个Comparator
,以便它可以比较它们。
即使您的元素是 Comparable
,您仍然可以在构建 SortedSet
时提供一个 Comparator
。如果您需要以不同于 compareTo()
方法中实现的顺序对元素进行排序,这将非常有用。
排序和排序有什么区别?
List
按添加元素的顺序保存其元素,而SortedSet
按排序顺序保存其元素。对元素进行排序意味着,在遍历集合时获得的第一个元素将是最小的元素,从给定的比较逻辑的角度来看。对元素进行排序意味着,您在列表中添加元素的顺序在该列表的生命周期内保持不变。因此,在遍历列表时获得的第一个元素是添加到列表中的第一个元素。
SortedSet
向 Set
添加了一些操作。以下是您可以使用 SortedSet
执行的操作。
遍历 SortedSet
中的元素将从最小元素到最大元素进行。
NavigableSet
不会改变 SortedSet
的行为。它在 SortedSet
上添加了一些非常有用的操作,其中包括以降序遍历元素的可能性。您将在后面看到更多关于这方面的细节。
上次更新: 2021 年 9 月 14 日