-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSortedAndNavigableSet.java
More file actions
144 lines (130 loc) · 6.32 KB
/
Copy pathSortedAndNavigableSet.java
File metadata and controls
144 lines (130 loc) · 6.32 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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package Phase5_CollectionsLambdasStreams.Collections;
import java.util.Comparator;
import java.util.NavigableSet;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* SortedSet and NavigableSet - Two Layered Interfaces on Top of Set
* -----------------------------------------------------------------
* The Set hierarchy actually has three levels:
* <p>
*
* Set (no order at all)
* |
* v
* SortedSet (elements come out in an order; range queries)
* |
* v
* NavigableSet (SortedSet + neighbour queries + descending view)
* <p>
*
* Both extra interfaces exist primarily to give SORTED set implementations
* a richer contract. TreeSet implements NavigableSet (and therefore
* SortedSet); ConcurrentSkipListSet does too.
* <p>
*
* SortedSet<E> - Methods Added Over Set
* --------------------------------------
* Comparator<? super E> comparator() - the order rule; null = natural
* E first() - smallest element (throws if empty)
* E last() - largest element (throws if empty)
* SortedSet<E> headSet(E toEl) - strictly less than toEl
* SortedSet<E> tailSet(E fromEl) - fromEl inclusive
* SortedSet<E> subSet(E fromEl, E toEl) - fromEl inclusive, toEl exclusive
* <p>
*
* NavigableSet<E> - Methods Added Over SortedSet
* ----------------------------------------------
* Neighbour queries (return null if not found):
* E lower(E e) - greatest element STRICTLY LESS than e
* E floor(E e) - greatest element <= e
* E ceiling(E e) - smallest element >= e
* E higher(E e) - smallest element STRICTLY GREATER than e
* <p>
*
* Polling (remove and return):
* E pollFirst() - remove and return smallest, or null
* E pollLast() - remove and return largest, or null
* <p>
*
* Reverse views:
* NavigableSet<E> descendingSet()
* Iterator<E> descendingIterator()
* <p>
*
* Inclusive-flag range views:
* NavigableSet<E> headSet(E toEl, boolean inclusive)
* NavigableSet<E> tailSet(E fromEl, boolean inclusive)
* NavigableSet<E> subSet(E from, boolean fromInclusive,
* E to, boolean toInclusive)
* <p>
*
* Why Have Both?
* --------------
* SortedSet has been around since Java 1.2. NavigableSet (added in Java 6)
* is the strict superset with the more useful "find a neighbour" API. New
* code is encouraged to type variables as NavigableSet whenever feasible -
* you get the full toolkit and can still pass to APIs that accept SortedSet
* or plain Set.
* <p>
*
* Implementations
* ---------------
* TreeSet - the everyday choice. Red-black tree.
* ConcurrentSkipListSet - same operations, thread-safe.
*/
public class SortedAndNavigableSet {
public static void main(String[] args) {
section("1) SortedSet methods on a TreeSet");
SortedSet<Integer> s = new TreeSet<>(java.util.List.of(50, 10, 30, 40, 20));
System.out.println("set = " + s);
System.out.println("comparator() = " + s.comparator()); // null -> natural order
System.out.println("first() = " + s.first());
System.out.println("last() = " + s.last());
System.out.println("headSet(30) = " + s.headSet(30)); // [10, 20]
System.out.println("tailSet(30) = " + s.tailSet(30)); // [30, 40, 50]
System.out.println("subSet(20,40) = " + s.subSet(20, 40));// [20, 30]
section("2) Custom Comparator changes 'sorted' meaning");
SortedSet<String> byLen = new TreeSet<>(Comparator.comparingInt(String::length));
byLen.add("kiwi");
byLen.add("fig");
byLen.add("date");
byLen.add("apple");
System.out.println("byLen = " + byLen);
System.out.println("comparator = " + byLen.comparator());
section("3) NavigableSet - the neighbour queries");
NavigableSet<Integer> ns = new TreeSet<>(java.util.List.of(10, 20, 30, 40, 50));
System.out.println("lower(30) = " + ns.lower(30)); // 20 (strict)
System.out.println("floor(30) = " + ns.floor(30)); // 30 (inclusive)
System.out.println("ceiling(30) = " + ns.ceiling(30)); // 30 (inclusive)
System.out.println("higher(30) = " + ns.higher(30)); // 40 (strict)
System.out.println("lower(0) = " + ns.lower(0)); // null - none
section("4) Polling - remove and return the extremes");
System.out.println("pollFirst() = " + ns.pollFirst() + " set=" + ns);
System.out.println("pollLast() = " + ns.pollLast() + " set=" + ns);
section("5) Inclusive-flag range views");
NavigableSet<Integer> ns2 = new TreeSet<>(java.util.List.of(10, 20, 30, 40, 50));
System.out.println("headSet(30, true) = " + ns2.headSet(30, true)); // [10,20,30]
System.out.println("headSet(30, false) = " + ns2.headSet(30, false)); // [10,20]
System.out.println("subSet(20,true,40,true) = " + ns2.subSet(20, true, 40, true)); // [20,30,40]
System.out.println("subSet(20,false,40,true) = " + ns2.subSet(20, false, 40, true)); // [30,40]
section("6) descendingSet - LIVE reverse view");
NavigableSet<Integer> rev = ns2.descendingSet();
System.out.println("ns2.descendingSet() = " + rev);
rev.pollFirst(); // removes the LARGEST in ns2
System.out.println("ns2 after rev.pollFirst() = " + ns2);
section("7) Practical use - quickest \"smallest score >= 60\"");
NavigableSet<Integer> scores = new TreeSet<>(java.util.List.of(42, 55, 67, 72, 88, 91));
Integer pass = scores.ceiling(60);
System.out.println("smallest passing score = " + pass); // 67
section("8) Reverse iteration with descendingIterator");
java.util.Iterator<Integer> it = ns2.descendingIterator();
System.out.print("desc iter: ");
while (it.hasNext()) System.out.print(it.next() + " ");
System.out.println();
// OUTPUT (representative)
}
private static void section(String title) {
System.out.println("\n====== " + title + " ======");
}
}