-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSequencedCollections.java
More file actions
96 lines (87 loc) · 4.03 KB
/
Copy pathSequencedCollections.java
File metadata and controls
96 lines (87 loc) · 4.03 KB
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
95
96
package Phase9_ModernJavaAndModules.ModernJava;
import java.util.*;
/**
* Sequenced Collections (Java 21)
* -------------------------------
* Before Java 21, getting the FIRST or LAST element of a List, LinkedHashSet,
* or LinkedHashMap was awkward: list.get(0), list.get(list.size()-1),
* iterator().next(), etc.
* <p>
*
* Java 21 introduces three new interfaces under java.util:
* <p>
*
* SequencedCollection<E> (parent of List, Deque, LinkedHashSet)
* SequencedSet<E> (extends SequencedCollection)
* SequencedMap<K, V> (LinkedHashMap, TreeMap)
* <p>
*
* They provide a UNIFORM API for ordered collections:
* <p>
*
* addFirst(e) addLast(e)
* getFirst() getLast()
* removeFirst() removeLast()
* reversed() // a view in reverse order
* <p>
*
* SequencedMap adds:
* firstEntry() lastEntry()
* putFirst(k, v) putLast(k, v)
* pollFirstEntry() pollLastEntry()
* sequencedKeySet() sequencedValues() sequencedEntrySet()
* <p>
*
* Why It Matters
* --------------
* - One mental model across List / Deque / LinkedHashSet / LinkedHashMap.
* - No more list.get(list.size() - 1) and the off-by-one bugs around it.
* - reversed() returns a VIEW - cheap, no copy.
*/
public class SequencedCollections {
public static void main(String[] args) {
// --- 1) ArrayList - already a SequencedCollection in 21 ---
SequencedCollection<String> list = new ArrayList<>(List.of("b", "c", "d"));
list.addFirst("a");
list.addLast("e");
System.out.println("list = " + list); // [a, b, c, d, e]
System.out.println("list.getFirst() = " + list.getFirst());// a
System.out.println("list.getLast() = " + list.getLast()); // e
System.out.println("list.reversed() = " + list.reversed()); // [e, d, c, b, a]
// reversed() is a VIEW - mutations propagate back to the original.
list.reversed().removeFirst(); // removes 'e' from the back of list
System.out.println("after reverse-pop = " + list); // [a, b, c, d]
// --- 2) LinkedHashSet is now a SequencedSet ---
SequencedSet<Integer> set = new LinkedHashSet<>(List.of(2, 3, 4));
set.addFirst(1);
set.addLast(5);
System.out.println("set = " + set); // [1, 2, 3, 4, 5]
System.out.println("set.reversed() = " + set.reversed());// [5, 4, 3, 2, 1]
// --- 3) LinkedHashMap is now a SequencedMap ---
SequencedMap<String, Integer> map = new LinkedHashMap<>();
map.put("two", 2);
map.put("three", 3);
map.putFirst("one", 1);
map.putLast("four", 4);
System.out.println("map = " + map); // {one=1, two=2, three=3, four=4}
System.out.println("map.firstEntry() = " + map.firstEntry()); // one=1
System.out.println("map.lastEntry() = " + map.lastEntry()); // four=4
System.out.println("map.reversed() = " + map.reversed()); // {four=4, three=3, two=2, one=1}
System.out.println("map.pollFirstEntry() = " + map.pollFirstEntry()); // one=1, removed
System.out.println("map after poll = " + map); // {two=2, three=3, four=4}
// OUTPUT (matches the inline comments above)
// list = [a, b, c, d, e]
// list.getFirst() = a
// list.getLast() = e
// list.reversed() = [e, d, c, b, a]
// after reverse-pop = [a, b, c, d]
// set = [1, 2, 3, 4, 5]
// set.reversed() = [5, 4, 3, 2, 1]
// map = {one=1, two=2, three=3, four=4}
// map.firstEntry() = one=1
// map.lastEntry() = four=4
// map.reversed() = {four=4, three=3, two=2, one=1}
// map.pollFirstEntry() = one=1
// map after poll = {two=2, three=3, four=4}
}
}