10 new features or treasures in Java 11 | JDK 11
There are a few 🏆 treasures that have been added as a part of JDK 11 and help developers to minimize coding efforts. Some of them you definitely know such as responsive Http2/API, you can run the source code directly without compiling. However, have you tried extensions of common classes such as String, Optional, Collections and Files, and if you haven’t already, congratulations, you’ll learn about some of them in this article.
You can download the JDK 11 from this link.
1. Local parameter type inference for Lambda Expressions
JDK 11 allows var
keyword to be used when declaring the formal parameters of implicitly typed lambda expressions:
Function<String, String> append = (var string) -> string + " World"; String appendedString = append.apply("Hello"); System.out.println(appendedString);
It’s not just adding the var
keyword to the variable that omits the type. The JDK 11 also allow annotations to be added to lambda’s parameters without having to write full variable type name. Let’s take a look at with example:
Function<String, String> append = (@NonNull var string) -> string + " World"; String appendedString = append.apply("Hello"); System.out.println(appendedString); // Output of above program Hello World
Now the apply method inside the Function accepts the NonNull value.
2. Usage of String:: repeat method to copy a String
A String method for repeating sequences of characters has been long requested from a user in StackOverflow.
Now from JDK 11, we have a repeat method that does exactly what we need.
var str = "abc"; var repeated = str.repeat(3); System.out.println(repeated); // Output of above program abcabcabc
3. Create a Path with Path::of method
I really like the Path API, which solves the problem of switching between paths, URIs, URLs, and FILEs. In Java 11 we can use Paths::get and Path::of methods to make them very uniform.
Path googlePath = Path.of(URI.create("www.google.com")) Path studentFilePath = Path.of("/home/Students/student.txt")
4. Files::readString and Files::writeString for file reading and Writing
If you need to read content from a very large file, we generally use lines method which returns a lazy stream. Similarly, if you want to store content in a file at the same time, I usually write to the files using the write method by passing an Iterable.
But in JDK 11, two methods of readString and writeString have been added to Files class.
String studentFileContent = Files.readString(Path.of("student.txt")) String modifiedStudentContent = addNewSubject(studentFileContent) Files.writeString(Path.of("student-mod.txt"),modifiedStudentContent)
5. String::lines to get the number of data Rows
You have a multi-line string and you want to do a separate operation for each line. You can do this with String::lines method.
var multiline = "My\nname is\nahsen saeed"; Stream<String> stream = multiline.lines(); stream.map(String::toUpperCase) .forEach(System.out::println); // Output of above program MY NAME IS AHSEN SAEED
The lines in the Stream are in the order in which they occur in the string. Unlike split, the new lines method is lazy.
Note: The new line in a string in the above example uses \n in Windows. Although, I’m using it in Linux, lines method can still split them. In a different operating system, the lines method will use \r, \n, \r\n as terminators. Even if we mix them in a string.
6. Usage of Optional::isEmpty instead of isPresent
Almost in every application, we need to check that if the value exists or not and for that, we often use the Optional::isPresent
method. I know! there is no problem in writing that, but writing does not understand the meaning of well. Now if we need to check that the value is empty inside the Optional::isPresent
method then we add the !
operator at the front.
val optional: Optional<String> = Optional.empty() if(!optional.isPresent) // value is empty
This !
is easily forgotten on Optional starting with Java 11, we have a better solution.
val optional: Optional<String> = Optional.empty() if (optional.isEmpty) { // value is empty }
The isEmpty method is used to return true if the value is not present.
7. Handling regular expressions with Pattern::asMatchPredicate
You have a regular expression and want to do some filtering based on it. What do you do?
Pattern<String> chracterPredicate = Pattern.compile("ah").asPredicate(); Stream.of("coding","ahsan","infinite") .filter(chracterPredicate) .forEach(System.out::println); // Output of above program ahsan
We had the asPredicate method as part of JDK 8, which will create a Predicate if and only if the given Pattern is found in a given string.
In JDK 11 we’ve another method Pattern::asMatchPredicate. So, what is the difference between them:
- asPredicate: Under the hood, the asPredicate method called
matcher(s).find()
. - asMatchPredicate: It will checks if the entire string conforms to this regular expression. This method behaves like
matcher(s).matches()
.
Now let’s say you have a regular expression that verifies the email.
private static final String EMAIL_PATTERN = "^[a-zA-Z0-9#_~!$&'()*+,;=:.\"<>@\\[\\]\\\\]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$"; var pattern = Pattern.compile(EMAIL_PATTERN).asMatchPredicate(); Stream.of("[email protected]") .filter(pattern) .forEach(sendEmailToMySecretary);
You see the asMatchPredicate method checks our regular expression internally and return the email if it is matched with the regular expression.
8. Usage of the strip, stripLeading, and stripTrailing
JDK 11 introduces the strip methods, which have some subtle differences from trim, let’s see them one by one:
8.1 strip
The strip()
method is used to remove the leading and trailing whitespaces. It is helpful to remove the white space from the beginning and the end of a string.
var s = " Michale "; String stripResult = s.strip(); System.out.println(stripResult) // Output of above program "Michale"
8.2 stripLeading
The stripLeading()
method is used to remove the white space from the beginning of a string.
var s = " Michale "; String stripLeadingResult = s.stripLeading(); System.out.println(stripLeadingResult) // Output o above program "Michale "
8.3 stripTrailing
The stripTrailing()
method is used to remove the white spaces from the end of a string.
var s = " Michale "; String stripTrailingResult = s.stripTrailing(); System.out.println(stripTrailingResult) // Output of above program " Michale"
9. Handle empty I/O operations with null StreamReader
What do you do when you need an InputStream that doesn’t process any data? What about an empty OutputStream, Reader or maybe Writer? In Java 11 you can do the following conversions:
InputStream inputStream = InputStream.nullInputStream(); OutputStream outputStream = OutputStream.nullOutputStream(); Reader reader = Reader.nullReader(); Writer writer = Writer.nullWriter();
10. Convert collections to arrays using Collection::toArray
How did you turn the collection into an array before Java 11?
Studen[] studentArray = studentList.toArray(new Student[0]);
The above toArray method returns an array if the list fits in the specified array. Otherwise, a new array is allocated with the runtime type of the specified array and size of the list.
Now that we have a method which returns an array of specified type T
. Why do we need another function? Is there a better way to handle it? In Java 11, you can do this:
Student[] studentArray = studentList.toArray(Student[]::new);
This is a new overloading method used by collection classes to receive IntFunction. The above Collection::toArray method returns an array of the corresponding length based on the length of the input data. It can be expressed in a brief and clear manner as T[]::new
.
What’s next
Closing Up
Hope you found this story useful and interesting. Feel free to share your feedback and comments below.
Thank you for being here and keep reading…
thank you, it was really great!
Really appreciate your great work…
Keep this going please, great job!