There’s a lot more to this release than modules.
By Simon Ritter
Author Simon Ritter is deputy CTO of Azul Systems.
The big new feature in JDK 9 is the Java Platform Module System coupled with the introduction of the modular JDK. However, there are plenty of other new features in JDK 9, and in this article, I focus on nine that are of particular interest to developers. Where applicable, I’ve included the relevant JDK Enhancement Proposal (JEP) number so you can find more information.
Collections provide a well understood way for you to gather together groups (I was going to say sets, but that could be a bit misleading) of data items in your applications and then manipulate the data in a variety of useful ways.
At the top level, there are interfaces that represent the abstract concepts of a
The problem, until now, has been that Java doesn’t provide a simple way to create a collection with predefined data. If you want a collection to be structurally immutable (that is, you can’t add, delete, or change references to elements), you need to do more work.
Let’s look at a simple example using JDK 8:
List<Point> myList = new ArrayList<>); myList.add(new Point(1, 1)); myList.add(new Point(2, 2)); myList.add(new Point(3, 3)); myList.add(new Point(4, 4)); myList = Collections.unmodifiableList(myList);
It’s not terrible, admittedly, but to create an immutable list of four
Points required six lines of code. JDK 9 addresses this through factory methods for collections.
This feature makes use of a change introduced in JDK 8 that enabled static methods to be included in interfaces. That change means that you can add the necessary methods at the top-level interfaces (
Map) rather than having to add them to a large group of classes that implement those interfaces.
Let’s rewrite our example using JDK 9:
List<Point> list = List.of(new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(4, 4));
The code is now much simpler.
The rules that apply to the use of the different collections also apply (as you would expect) when using these factory methods. So, you cannot pass duplicate arguments when you create a
Set, nor can you pass duplicate keys when you create a
null value cannot be used as a value for any collection factory method. The Javadoc documentation provides full descriptions of how the methods may be called. [For more on collections, read the article “Java 9 Core Library Updates: Collections and Streams,” in Java Magazine July/August 2017.—Ed.]
Optional class was introduced in JDK 8 to reduce the number of places where a
NullPointerException could be generated by code (and it was frequently used to make the Stream API more robust).
JDK 9 adds four new methods to
ifPresent(Consumer action): If there is a value present, perform the action using the value.
ifPresentOrElse(Consumer action, Runnable emptyAction): Similar to
ifPresent, but if there is no value, it executes the
or(Supplier supplier): This method is useful when you want to ensure that you always have an
or()method returns the same
Optionalif a value is present; otherwise, it returns a new
Optionalcreated by the
stream(): Returns a stream of zero or one elements, depending on whether there is a value.
It’s always useful to be able to create a stream source from a collection of data, and JDK 8 provided several methods to do this outside the Collections API (
BufferedReader.lines(), for example). Several new sources are being added in JDK 9, such as
JDK 9 adds four methods to the
First, there are two related methods:
dropWhile(Predicate). These methods are complementary to the existing
skip() methods, but they use a
Predicate rather than a fixed integer value. The
takeWhile() method continues to take elements from the input stream and pass them to the output stream until the
test() method of the
Predicate returns true. The
dropWhile() method does the opposite; it drops elements from the input stream until the
test() method of the
Predicate returns true. All remaining elements of the input stream are then passed to the output stream.
Be careful when using either of these methods when you have an unordered stream. Because the predicate needs to be satisfied only once to change the state of elements being passed to the output, you might get elements in the stream that you don’t expect, or you might miss ones you thought you would get.
The third new method is
ofNullable(T t), which returns a stream of zero or one elements, depending on whether the value passed is
null. This can be very useful to eliminate a null check before constructing a stream, and it is similar in a sense to the new
stream() method in the
Optional class discussed in the previous section.
The last new stream method is a new version of the static
iterate() method. The version in JDK 8 took one parameter as the seed and created an infinite stream as output. JDK 9 adds an overloaded method that takes three parameters, which effectively gives you the ability to replicate the standard for loop syntax as a stream. For example,
Stream.iterate(0, i -> i < 5, i -> i + 1) gives you a stream of integers from 0 to 4.
Simon Ritter (@speakjava) is the deputy CTO of Azul Systems. He has been in the IT business since 1984 and holds a BS in physics from Brunel University in the UK. He joined Sun Microsystems in 1996 and spent time working in both Java development and consultancy. Ritter has been presenting Java technologies to developers since 1999, focusing on the core Java platform as well as client and embedded applications.
Photograph by Bob Adler/The Verbatim Agency