1. Overview
1.概述
Java 21 is expected to be released on September 2023, being the next long-term support release after Java 17. Among the new features, we can identify an update of Java’s collections framework called Sequenced Collections.
Java 21 预计将于 2023 年 9 月发布,是继 Java 17 之后的下一个长期支持版本。在新功能中,我们可以发现 Java 的集合框架进行了更新,称为序列集合。
The Sequenced Collections proposal stands out as a game-changing enhancement that promises to redefine how developers interact with collections. This feature injects new interfaces into the existing hierarchy, offering a seamless mechanism to access the first and last elements of a collection using built-in default methods. Moreover, it provides support to obtain a reversed view of the collection.
序列集合提案是一项改变游戏规则的增强功能,有望重新定义开发人员与集合的交互方式。该功能为现有的层次结构注入了新的接口,提供了一种无缝机制,可使用内置的默认方法访问集合的第一个和最后一个元素。此外,它还支持获得集合的反向视图。
In this article, we will explore this new enhancement, its potential risks, and the advantages it brings.
在本文中,我们将探讨这一新的增强功能、其潜在风险以及带来的优势。
2. Motivation
2.动机
The absence of a universal supertype for collections with a defined encounter order has been a repeated source of problems and complaints. Additionally, the lack of uniform methods for accessing first and last elements and iterating in reverse order has been a persistent limitation of Java’s collections framework.
对于具有已定义相遇顺序的集合而言,缺乏通用的超级类型一直是问题和抱怨的根源。此外,缺乏访问首元素和尾元素以及按相反顺序迭代的统一方法也是 Java 的 集合框架一直存在的限制。
We can take as an example List and Deque: both define an encounter order, but their common supertype, Collection, does not. Similarly, Set does not define an encounter order, but some subtypes, such as SortedSet and LinkedHashSet, do. Support for encounter order is thus spread across the type hierarchy, and operations related to encounter order are either inconsistent or missing.
我们可以以 List 和 Deque 为例:它们都定义了相遇顺序,但它们的共同超类型 Collection 却没有。同样,Set 没有定义相遇顺序,但一些子类型,如 SortedSet 和 LinkedHashSet 却定义了相遇顺序。因此,对相遇顺序的支持分布在整个类型层次中,与相遇顺序相关的操作要么不一致,要么缺失。
In order to demonstrate the inconsistency, let’s make a comparison of accessing the first and last elements of different collection types:
为了证明这种不一致性,让我们比较一下访问不同集合类型的第一个和最后一个元素的情况:
Accessing the first element | Accessing the last element | |
---|---|---|
List | list.get(0) | list.get(list.size() – 1) |
Deque | deque.getFirst() | deque.getLast() |
SortedSet | sortedSet.first() | sortedSet.last() |
LinkedHashSet | linkedHashSet.iterator().next() | // missing |
The same thing happens when trying to get a reversed view of a collection. While iterating the elements of a collection from the first to the last element follows a clear and consistent pattern, doing so in the opposite direction presents challenges.
当试图获得一个集合的反向视图时,也会发生同样的情况。虽然从第一个元素到最后一个元素迭代集合中的元素遵循清晰一致的模式,但反向迭代却带来了挑战。
To illustrate, when dealing with a NavigableSet, we can use the descendingSet() method. For a Deque, the descendingIterator() method proves useful. Similarly, when dealing with a List, the listIterator() method works well. However, this is not the case for LinkedHashSet, as it doesn’t provide any support for reverse iteration.
举例说明,在处理 NavigableSet 时,我们可以使用 descendingSet() 方法。对于 Deque 来说,descendingIterator() 方法证明是有用的。同样,在处理 List 时,listIterator() 方法也很有效。但是,LinkedHashSet 并非如此,因为它不支持反向迭代。
All these differences led to fragmented codebases and complexity, making it challenging to express certain useful concepts in APIs.
所有这些差异导致了代码库的分散和复杂性,使得在 API 中表达某些有用的概念变得十分困难。
3. The New Java Collection Hierarchy
3.新的 Java 集合层次结构
This new feature introduces three new interfaces for sequenced collections, sequenced sets, and sequenced maps, which are added to the existing hierarchy of collections:
这项新功能为序列化集合、序列化集合和序列化映射引入了三个新接口,并将其添加到现有的集合层次结构中: <br
This image is part of the official documentation for JEP 431: Sequenced Collections (source).
该图片是 JEP 431:序列集合 (source) 官方文档的一部分。
3.1. SequencedCollection
3.1.序列集合</em
A sequenced collection is a Collection whose elements have a defined encounter order. The new SequencedCollection interface provides methods to add, retrieve, or remove elements at both ends of the collection, along with a method to get a reverse-ordered view of the collection.
<新的 SequencedCollection 接口提供了用于添加、检索或删除集合两端元素的方法,以及用于获取集合反序视图的方法。
interface SequencedCollection<E> extends Collection<E> {
// new method
SequencedCollection<E> reversed();
// methods promoted from Deque
void addFirst(E);
void addLast(E);
E getFirst();
E getLast();
E removeFirst();
E removeLast();
}
All methods, except reversed(), are default methods, provide a default implementation, and are promoted from Deque. The reversed() method provides a reversed-order view of the original collection. Also, any modifications to the original collection are visible in the reversed view.
除reversed()外,所有方法都是默认方法,提供默认实现,并从 Deque 推广而来。reversed() 方法提供了原始集合的逆序视图。此外,对原始集合的任何修改都可以在反转视图中看到。
The add*() and remove*() methods are optional and throw an UnsupportedOperationException in their default implementation, primarily to support the case of unmodifiable collections and collections with an already defined sorting order. The get*() and remove*() methods throw NoSuchElementException if the collection is empty.
add*()和remove*()方法是可选的,在默认实现中会抛出UnsupportedOperationException,主要用于支持不可修改的集合和已定义排序顺序的集合。如果集合为空,get*() 和 remove*() 方法会抛出 NoSuchElementException 异常。
3.2. SequencedSet
3.2.序列集</em
A sequenced set can be defined as a specialized Set which functions as a SequencedCollection, ensuring the absence of duplicate elements. The SequencedSet interface extends SequencedCollection and overrides its reversed() method. The only difference is that the return type of SequencedSet.reversed() is SequencedSet.
排序集可被定义为专门的Set,其功能类似于SequencedCollection,可确保没有重复元素。SequencedSet接口扩展了 SequencedCollection,并覆盖了其reversed()方法。唯一的区别是, SequencedSet.reversed() 的返回类型是 SequencedSet。
interface SequencedSet<E> extends Set<E>, SequencedCollection<E> {
// covariant override
SequencedSet<E> reversed();
}
3.3. SequencedMap
3.3.序列图</em
A sequenced map is a Map whose entries have a defined encounter order. The SequencedMap does not extend SequencedCollection and provides its own methods to manipulate elements at either end of the collection.
排序地图是一个Map,其条目具有定义的相遇顺序。SequencedMap没有扩展SequencedCollection,它提供了自己的方法来操作集合两端的元素。
interface SequencedMap<K, V> extends Map<K, V> {
// new methods
SequencedMap<K, V> reversed();
SequencedSet<K> sequencedKeySet();
SequencedCollection<V> sequencedValues();
SequencedSet<Entry<K, V>> sequencedEntrySet();
V putFirst(K, V);
V putLast(K, V);
// methods promoted from NavigableMap
Entry<K, V> firstEntry();
Entry<K, V> lastEntry();
Entry<K, V> pollFirstEntry();
Entry<K, V> pollLastEntry();
}
Similar to SequencedCollection, put*() methods throw UnsupportedOperationException for unmodifiable maps or maps with an already defined sorting order. Also, calling one of the methods promoted from NavigableMap on an empty map leads to throwing a NoSuchElementException.
与 SequencedCollection 类似,对于不可修改的地图或已定义排序顺序的地图,put*() 方法会抛出 UnsupportedOperationException 异常。此外,在空地图上调用从 NavigableMap 升级的方法之一会导致抛出 NoSuchElementException 异常。
4. Risks
4.风险
The introduction of the new interfaces is supposed not to affect code that simply uses collections implementations. However, there are several kinds of conflicts that may appear if custom collection types would be defined in our codebases:
新接口的引入应该不会影响那些简单使用集合实现的代码。不过,如果在我们的代码库中定义了自定义集合类型,可能会出现几种冲突:
- method naming: new methods introduced might clash with methods on existing classes. For example, if we have a custom implementation of the List interface that already defines a getFirst() method but with a different return type than getFirst() defined in SequencedCollection, it will create a source incompatibility when upgrading to Java 21.
- covariant overrides: both List and Deque provide covariant overrides of the reversed() method, one returning List and the other one returning Deque. Therefore, any custom collection that implements both interfaces will lead to a compile-time error when upgrading to Java 21 because the compiler can’t choose one over the other.
The report JDK-8266572 contains a full analysis of the incompatibility risk.
报告JDK-8266572包含对不兼容风险的全面分析。
5. Conclusion
5.结论
In conclusion, Sequenced Collections marks a significant leap forward for the Java Collections. By addressing the long-standing need for a unified way to handle collections with a defined encounter order, Java empowers developers to work more efficiently and intuitively. The new interfaces establish a clearer structure and consistent behavior, resulting in more robust and readable code.
总之,有序集合标志着Java 集合的重大飞跃。通过解决长期以来以统一方式处理具有已定义相遇顺序的集合的需求,Java 使开发人员能够更高效、更直观地工作。新的接口建立了更清晰的结构和一致的行为,从而使代码更健壮、更易读。
As always, the source code is available over on GitHub.
与往常一样,源代码可在 GitHub 上获取。