一、摘要

引入新的接口来表示具有定义的出现顺序的集合。每个这样的集合具有定义明确的第一元素、第二元素等等,直到最后一个元素。它还提供了统一的API,用于访问它的第一个和最后一个元素,以及以相反的顺序处理它的元素。

二、动机

Java 的集合框架缺少一种元素具有确定的出现顺序的集合类型。它还缺乏一套适用于此类集合的统一操作。这些缺陷一直是问题和抱怨的反复来源。

例如,ListDeque 都定义了元素出现的顺序,它们的共同超类型是 Collection,而 Collection 并没有定义元素出现顺序。同样,Set 也没有定义元素出现顺序,并且像 HashSet 这样的子类型也没有定义,但像 SortedSetLinkedHashSet 这样的子类型却有。因此,对出现顺序的支持分散在类型层次结构中,这使得在 API 中表达某些有用的概念变得困难。CollectionList 都不能描述具有出现顺序的参数或返回值。Collection 太笼统,只能在文档说明中规定此类约束,可能导致难以调试的错误。List 又太具体,排除了 SortedSetLinkedHashSet

三、详情

为有序集合、有序集合和有序映射定义了新的接口,然后将它们重新集成到现有的集合类型层次结构中。这些接口中声明的所有新方法都有默认实现。

1、sequenced collections

一种具有明确定义的遍历顺序、支持两端操作并且是可以反转的集合。

序列集合的元素具有遍历顺序,从概念上讲,元素从第一个元素到最后一个元素具有线性排列。对于任意两个元素,一个元素要么在另一个元素之前(更接近第一个元素),要么在另一个元素之后(更接近最后一个元素)。注意,这个定义并不意味着关于元素的物理位置的任何内容,例如它们在计算机内存中的位置。

Collection 接口继承的几个方法需要根据这个集合的遍历顺序对元素进行操作。例如,iterator 方法从第一个元素开始提供元素,依次遍历后续元素,直到最后一个元素。其他需要按照遍历顺序对元素进行操作的方法包括:forEachparallelStreamspliteratorstream 以及 toArray 方法的所有重载。

这个接口提供了在集合的两端添加、检索和删除元素的方法。 这个接口还定义了 reversed 方法,它提供了这个集合的逆序视图。在逆序视图中,“第一个”和“最后一个”的概念被颠倒,“后继者”和“前驱者”的概念也被颠倒。这个集合的第一个元素是逆序视图的最后一个元素,反之亦然。这个集合中某个元素的后继者在逆序视图中是它的前驱者,反之亦然。

所有遵循集合遍历顺序的方法在操作时就好像遍历顺序被颠倒了一样。例如,逆序视图的 iterator 方法按从这个集合的最后一个元素到第一个元素的顺序遍历元素。reversed 方法的可用性及其对所有相关方法的排序语义的影响,允许以正向或反向顺序对这个集合的元素进行迭代、搜索、复制和流式处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public interface SequencedCollection<E> extends Collection<E> {

SequencedCollection<E> reversed();

default void addFirst(E e) {
throw new UnsupportedOperationException();
}

default void addLast(E e) {
throw new UnsupportedOperationException();
}

default E removeFirst() {
var it = this.iterator();
E e = it.next();
it.remove();
return e;
}

default E removeLast() {
var it = this.reversed().iterator();
E e = it.next();
it.remove();
return e;
}

default E getFirst() {
return this.iterator().next();
}

default E getLast() {
return this.reversed().iterator().next();
}
}

接口的方法包括:

  • reversed 方法返回一个逆序的 SequencedCollection 对象。
  • addFirstaddLast 方法分别在集合的起始和结束位置添加新的元素。
  • getFirstgetLast 方法分别获取集合的第一个和最后一个元素。
  • removeFirstremoveLast 方法分别删除集合的第一个和最后一个元素。

2、sequenced sets

1
2
3
4
public interface SequencedSet<E> extends SequencedCollection<E>, Set<E> {

SequencedSet<E> reversed();
}

3、sequenced maps

序列 Map 指的是其中的元素具有出现顺序的 Map。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
public interface SequencedMap<K, V> extends Map<K, V> {

SequencedMap<K, V> reversed();


default Map.Entry<K,V> firstEntry() {
var it = entrySet().iterator();
return it.hasNext() ? new NullableKeyValueHolder<>(it.next()) : null;
}

default Map.Entry<K,V> lastEntry() {
var it = reversed().entrySet().iterator();
return it.hasNext() ? new NullableKeyValueHolder<>(it.next()) : null;
}

default Map.Entry<K,V> pollFirstEntry() {
var it = entrySet().iterator();
if (it.hasNext()) {
var entry = new NullableKeyValueHolder<>(it.next());
it.remove();
return entry;
} else {
return null;
}
}

default Map.Entry<K,V> pollLastEntry() {
var it = reversed().entrySet().iterator();
if (it.hasNext()) {
var entry = new NullableKeyValueHolder<>(it.next());
it.remove();
return entry;
} else {
return null;
}
}

default V putFirst(K k, V v) {
throw new UnsupportedOperationException();
}

default V putLast(K k, V v) {
throw new UnsupportedOperationException();
}

default SequencedSet<K> sequencedKeySet() {
class SeqKeySet extends AbstractMap.ViewCollection<K> implements SequencedSet<K> {
Collection<K> view() {
return SequencedMap.this.keySet();
}
public SequencedSet<K> reversed() {
return SequencedMap.this.reversed().sequencedKeySet();
}
public boolean equals(Object other) {
return view().equals(other);
}
public int hashCode() {
return view().hashCode();
}
}
return new SeqKeySet();
}

default SequencedCollection<V> sequencedValues() {
class SeqValues extends AbstractMap.ViewCollection<V> implements SequencedCollection<V> {
Collection<V> view() {
return SequencedMap.this.values();
}
public SequencedCollection<V> reversed() {
return SequencedMap.this.reversed().sequencedValues();
}
}
return new SeqValues();
}

default SequencedSet<Map.Entry<K, V>> sequencedEntrySet() {
class SeqEntrySet extends AbstractMap.ViewCollection<Map.Entry<K, V>>
implements SequencedSet<Map.Entry<K, V>> {
Collection<Map.Entry<K, V>> view() {
return SequencedMap.this.entrySet();
}
public SequencedSet<Map.Entry<K, V>> reversed() {
return SequencedMap.this.reversed().sequencedEntrySet();
}
public boolean equals(Object other) {
return view().equals(other);
}
public int hashCode() {
return view().hashCode();
}
}
return new SeqEntrySet();
}
}

接口的方法包括:

  • reversed 方法返回一个 entry 逆序的 SequencedMap
  • sequencedKeySet 方法返回包含 key 的 SequencedSet
  • sequencedValues 方法返回包含 value 的 SequencedCollection
  • sequencedEntrySet 方法返回包含 entry 的 SequencedSet
  • putFirstputLast 分别在 entry 的最前和最后位置插入名值对。
  • firstEntrylastEntry 分别获取第一个和最后一个 entry。
  • pollFirstEntrypollLastEntry 分别删除第一个和最后一个 entry。

四、原有类的改造

相关链接

JEP 431: Sequenced Collections (openjdk.org)

OB tags

#JDK新特性 #Java