23 lines
1.2 KiB
Plaintext
23 lines
1.2 KiB
Plaintext
A LinkedHashSet has a real iteration order, but pre-Java-21 Set has no getLast():
|
|
[home, search, product/42, cart, checkout]
|
|
|
|
Old #1 - stream().reduce((a,b) -> b): checkout
|
|
Old #2 - stream().skip(size - 1).findFirst(): checkout
|
|
Old #3 - new ArrayList<>(set).get(size-1): checkout
|
|
New - set.getLast(): checkout
|
|
|
|
All four agree: true
|
|
|
|
Why the old ways were worse than they looked:
|
|
- reduce((a,b)->b) walks the ENTIRE set, every time: O(n).
|
|
- skip(size-1).findFirst() also walks the entire stream pipeline up to size-1: O(n).
|
|
- new ArrayList<>(set) copies every element just to throw the copy away: O(n) time AND space.
|
|
- set.getLast() walks the SequencedCollection's default path to reversed().iterator().next();
|
|
for LinkedHashSet specifically, that's backed by LinkedHashMap's existing doubly-linked
|
|
insertion-order list, so it resolves in O(1) in the JDK's actual implementation - though
|
|
that O(1) is an implementation detail of LinkedHashMap, not a guarantee the interface makes.
|
|
|
|
On a List this was never actually hard - list.get(list.size()-1) already worked.
|
|
list.getLast() = c (same answer, no size() arithmetic, and it now
|
|
reads identically whether the underlying type is a List, a Deque, or a LinkedHashSet).
|