Abstract: Java 9 now offers immutable lists, sets and maps. We look at how to create them and also how to do simple set operations like union and intersection.
Welcome to the 248th edition of The Java(tm) Specialists' Newsletter. I hope you are doing well? I'm exhausted. On Monday I flew from Cape Town to Frankfurt, then to Munich and on to Sofia. I spoke at JPrime, then hopped on to an Air Bulgaria flight to Athens and then home with Olympic Air. It is fun speaking at conferences and I do try to help anyone that asks. But it does get tiring. A few weeks ago I spoke at three conferences in three countries in a space of three days. It was disorientating. Why do we do it? I think that the biggest win is that it forces me to think deeply about a particular subject. This then flows into my advanced Java courses.
javaspecialists.teachable.com: Please visit our new self-study course catalog to see how you can upskill your Java knowledge.
Exciting news. We now have "immutable collections" in Java 9. Just like Scala (not really).
For example, if we want to create lists, we can do this:
List<Integer> list0 = List.of(); // List0 List<Integer> list1 = List.of(42); // List1 List<Integer> list2 = List.of(42, 57); // List2 List<Integer> list3 = List.of(42, 57, 1); // ListN List<Integer> list4 = List.of(42, 57, 1, 2); // ListN
I mentioned this during our last "Heinz's
Happy Hour" session, and someone pointed out that the
lists returned by Arrays.asList()
were also
immutable. They are not. Whilst you cannot add and remove
elements, you can still set individual elements of the list.
We can create sets in a similar way, like so:
Set<Integer> set0 = Set.of(); // List0 Set<Integer> set1 = Set.of(42); // List1 Set<Integer> set2 = Set.of(42, 57); // List2 Set<Integer> set3 = Set.of(42, 57, 1); // ListN Set<Integer> set4 = Set.of(42, 57, 1, 2); // ListN
This begs the question: How can we do set operations? Let's take these sets:
Set<Integer> one = Set.of(1, 2, 3); Set<Integer> two = Set.of(3, 4, 5);
To create a union of these is a bit awkward, since there is no easy way to create an immutable Set from an ordinary Set. We could create a temporary Set and then the union from that, like so:
Set<Integer> temp = new HashSet<>(one); temp.addAll(two); Set<Integer> union = Set.of(temp.toArray(new Integer[0])); System.out.println("union = " + union);
I do not like temporary variables, so we could wrap this in a facade somewhere. To do the intersection is similar:
Set<Integer> temp = new HashSet<>(one); temp.retainAll(two); Set<Integer> intersection = Set.of(temp.toArray(new Integer[0])); System.out.println("intersection = " + intersection);
We can also create Maps with Map.of():
Map<String, Integer> map0 = Map.of(); Map<String, Integer> map1 = Map.of("one", 1); Map<String, Integer> map2 = Map.of("one", 1, "two", 2);
Map.of() works with key and value pairs up to 10 entries. Beyond that, we need to pass in a var-args of Entry instances and use Map.ofEntries(Entry...)
Map<String, Integer> mapN = Map.ofEntries( Map.entry("one", 1), Map.entry("two", 2), Map.entry("three", 3), Map.entry("four", 4), Map.entry("five", 5) );
It is, of course, not nearly as convenient as Kotlin/Swift/Scala/Groovy/etc. It's a very small addition to Java which you get when you go over to Java 9.
Kind regards from Crete
Heinz
We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)
We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.