Sequenced Collection
Its a great addition to the existing Collection framework which allows access to the first and last elements of a collection out-of-the-box (using its default methods). Apart from this, it also allow us to get the reversed view of our Collection.
Sequenced Collections are part of JPE-431.
Sequenced Collection introduced 3 new interfaces in the Collection framework hierarchy.
- SequencedCollection
- SequencedSet
- SequencedMap
Lets discuss more about them in details.
-
SequencedCollection Interface
The SequencedCollection interface introduced methods to add, get, and remove elements from the ends of the collection. It also provides a reversed() method which provides a reverse order view of the collection object.
public interface SequencedCollection<E> extends Collection<E> { SequencedCollection<E> reversed(); default void addFirst(E e) default void addLast(E e) default E getFirst() default E getLast() default E removeFirst() default E removeLast() }
Except for reversed(), all are default operations. For Example:
List<Integer> integerList = new ArrayList<>(); integerList.add(100); //[100] integerList.addFirst(50); //[50,100] integerList.addLast(150); //[50,100,150] integerList.getFirst(); //50 integerList.getLast(); //150 System.out.println(integerList.reversed()); //[150,100,50] //integerList = [50,100,150] integerList.removeFirst(); //[100,150] integerList.removeLast(); //[100]
-
SequencedSet Interface
SequencedSet interface extends SequencedCollection and is specific to the Set implementation. It overrides the reverse() method and returns a SequencedSet
. public interface SequencedSet<E> extends SequencedCollection<E>, Set<E> { SequencedSet<E> reversed(); }
Lets look into an example.
SequencedSet<Integer> integerSet = new LinkedHashSet<>(); integerSet.add(100); //[100] integerSet.addFirst(50); //[50,100] integerSet.addLast(150); //[50,100,150] integerSet.getFirst(); //50 integerSet.getLast(); //150 System.out.println(integerSet.reversed()); //[150,100,50]
-
SequencedMap Interface
It applies to the Map classes and as shown in the diagram above, it doesn’t extend the
SequencedCollection
interface but rather it provide its own methods for access order.public interface SequencedMap<K, V> extends Map<K, V> { SequencedMap<K, V> reversed(); default V putFirst(K k, V v) {} default V putLast(K k, V v) {} default Map.Entry<K,V> firstEntry(){} default Map.Entry<K,V> lastEntry() {} default Map.Entry<K,V> pollFirstEntry() {} default Map.Entry<K,V> pollLastEntry() {} default SequencedSet<K> sequencedKeySet() {} default SequencedCollection<V> sequencedValues() {} default SequencedSet<Map.Entry<K, V>> sequencedEntrySet() {} }
Lets again look at its example
SequencedMap<Integer,String> daysOfWeekMap = new LinkedHashMap<>(); daysOfWeekMap.put(2, "MONDAY"); daysOfWeekMap.put(3, "TUESDAY"); daysOfWeekMap.put(4, "WEDNESDAY"); daysOfWeekMap.put(5, "THURSDAY"); daysOfWeekMap.put(6, "FRIDAY"); //{2=MONDAY, 3=TUESDAY, 4=WEDNESDAY, 5=THURSDAY, 6=FRIDAY} daysOfWeekMap.putFirst(1, "SUNDAY"); daysOfWeekMap.putLast(7, "SATURDAY"); //{1=SUNDAY, 2=MONDAY, 3=TUESDAY, 4=WEDNESDAY, 5=THURSDAY, 6=FRIDAY, 7=SATURDAY} daysOfWeekMap.firstEntry(); //1=SUNDAY daysOfWeekMap.lastEntry(); //7=SATURDAY daysOfWeekMap.sequencedKeySet(); //[1, 2, 3, 4, 5, 6, 7] daysOfWeekMap.sequencedValues(); //[SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY] daysOfWeekMap.sequencedEntrySet(); //[1=SUNDAY, 2=MONDAY, 3=TUESDAY, 4=WEDNESDAY, 5=THURSDAY, 6=FRIDAY, 7=SATURDAY] daysOfWeekMap.pollFirstEntry(); daysOfWeekMap.pollLastEntry(); //{2=MONDAY, 3=TUESDAY, 4=WEDNESDAY, 5=THURSDAY, 6=FRIDAY}
-
Addition to Collections Class
In order to accommodate these new data types, new methods has been added to
Collections
class.Collections.unmodifiableSequencedCollection(sequencedCollection); Collections.unmodifiableSequencedSet(sequencedSet); Collections.unmodifiableSequencedMap(sequencedMap);
-
Common Exceptions
If we try to perform these operations on a immmutable data type or a collection which already have a specific order, an
UnsupportedOperationException
is thrownSequencedCollection<Integer> immutableList = List.of(1,2,3); immutableList.addFirst(0); SequencedMap<Integer,Integer> treeMap = new TreeMap<>(Map.of(1, 100, 2, 200)); treeMap.putLast(3, 300); /* Exception in thread "main" java.lang.UnsupportedOperationException at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142) at java.base/java.util.ImmutableCollections$AbstractImmutableList.add(ImmutableCollections.java:258) at java.base/java.util.List.addFirst(List.java:796) */
Similarly, when trying to fetch first or last elements from an empty collection results in
NoSuchElementException
SequencedSet<Integer> treeMap = new TreeSet<>(Set.of()); treeMap.getLast(); /* Exception in thread "main" java.util.NoSuchElementException at java.base/java.util.TreeMap.key(TreeMap.java:1637) at java.base/java.util.TreeMap.lastKey(TreeMap.java:309) at java.base/java.util.TreeSet.last(TreeSet.java:402) at java.base/java.util.SortedSet.getLast(SortedSet.java:320) */