Java Improvements from 8 to 11
Here we are going to look at some improvements between Java 8 and Java 11. But, before showing these new features, it is important to know the difference between LTS and non-LTS versions, and how the releases work now.
The LTS version is the Long-Term-Support, so they have more support than the others.
Since Java 17, the release program has been 2 new releases every year, one in March and one in September, and the interval between LTS versions is now two years instead of three.
If you want to know more about it: https://www.oracle.com/java/technologies/java-se-support-roadmap.html
Java 8 (LTS)
This is our first LTS release that we will talk about here. There are many projects that still use this version, as this version has extended support until December 2030.
But beware, there are many tools and frameworks that stop supporting this version, and the new versions contain new features that will help you gain productivity.
Stream
Java supports a sequence of operations that can be executed parallel or sequentially and with Lazy execution.
Example:
int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
.mapToInt(w -> w.getWeight())
.sum();
The Stream in Java contains two types of operations: terminal and intermediate. We can have multiple intermediate operations, but only one terminal operation for producing the result or the side effect.
Streams are lazy; computation on the source data is only performed when the terminal operation is initiated, and source elements are consumed only as needed.
If you want to know more about it: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
The most common Functional Interfaces
Functional interfaces provide target types for lambda expressions and method references. Each functional interface has a single abstract method, called the functional method for that functional interface, to which the lambda expression's parameter and return types are matched or adapted. Functional interfaces can provide a target type in multiple contexts, such as assignment context, method invocation, or cast context:
Most common Functional Interface:
Consumer: Represents an operation that accepts a single input argument and returns no result.
Function<T,R>: Represents a function that accepts one argument and produces a result.
Predicate: Represents a predicate (boolean-valued function) of one argument.
Supplier: Represents a supplier of results.
If you want to know more about it: https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
Optional
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
Optional should be used to avoid NPE(NullPointerException)
If you want to know more about it: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
Java 8 is a big version with a lot of news. Like LocalDate, LocalDateTime, CompletableFuture, updates into File API... I've shown only some news in this version if you want to know more about what's new in Java 8 access this links:
https://www.oracle.com/java/technologies/javase/8-whats-new.html
https://www.oracle.com/java/technologies/javase/8all-relnotes.html
Java 9
Java 9 is not an LTS version but brings many refactorings in Java internal structure.
Modules
Java changes a lot from version 8 to version 9 because of Modules.
According to JSR 376, the key goals of modularizing the Java SE platform are:
Reliable configuration
Strong encapsulation
Scalable Java platform
Greater platform integrity
Improved performance
"Each module must explicitly state its dependencies. "
"A key motivation of the module system is strong encapsulation."
If you want to know more about Java modules:
https://www.oracle.com/pt/corporate/features/understanding-java-9-modules.html
Improvements Stream on Java 9
takeWhile
default Stream takeWhile(Predicate<? super T> predicate)
Returns, if this stream is ordered, a stream consisting of the longest prefix of elements taken from this stream that match the given predicate. Otherwise, returns, if this stream is unordered, a stream consisting of a subset of elements taken from this stream that match the given predicate.
Example:
Stream<Integer> stream = Stream.iterate(1, i -> i <= 10, i -> i + 1);
stream = stream
.takeWhile(f -> f % 2 == 0);
//Next iteration will be 1, will return false and will end this
//execution with zero elements in the Stream.
return stream
.count(); //0
The takeWhile operation will keep elements while the given predicate for an element returns true;
dropWhile
default Stream dropWhile(Predicate<? super T> predicate)
Returns, if this stream is ordered, a stream consisting of the remaining elements of this stream after dropping the longest prefix of elements that match the given predicate. Otherwise returns, if this stream is unordered, a stream consisting of the remaining elements of this stream after dropping a subset of elements that match the given predicate.
Example:
Stream<Integer> stream = Stream
.iterate(1, i -> i <= 10, i -> i + 1);
stream = stream
.dropWhile(f -> f <= 4)
//The dropWhile operation will remove elements while the given predicate
//for an element returns true and stops removing on the first
//predicate's false.
.dropWhile(f -> f % 2 == 0);
//Next iteration will be 5, will return false and will end this //execution
return stream
.count(); //6
The dropWhile operation will remove elements while the given predicate for an element returns true and stops removing on the first predicate's false.
iterate
public static Stream iterate(T seed, Predicate<? super T> hasNext, UnaryOperator next)
Returns a sequential, ordered Stream produced by iterative application of the given next function to an initial element, conditioned on satisfying the given hasNext predicate. The stream terminates as soon as the hasNext predicate returns false.
This operation is lazy too.
For more information: https://www.baeldung.com/java-9-stream-api
Optional ifPresentOrElse
On Java 9 a new method was introduced on Optional ifPresentOrElse. This method receives a Consumer and also a Runnable for the else clause. Let’s see on example:
Optional.ofNullable(fullName)
.ifPresentOrElse(n -> {
String[] names = n.split(" ");
System.out.println(names[names.length-1]);
}, () -> System.out.println("Empty"));
If you want to know more about what's new in Java 9, I recommend see these links:
Java 10
Java 10 is also a non-LTS version, and we are going to see some new features introduced in this version.
Unmodifiable List in the Collection
Several new APIs have been added that facilitate the creation of unmodifiable collections. The List.copyOf, Set.copyOf, and Map.copyOf methods create new collection instances from existing instances.
Example:
List<Integer> newList = Lists.copyOf(otherList);
Optional.orElseThrow()
A new method, orElseThrow has been added to the Optional class. It works similarly to the get() method, but it is now the preferred alternative to the existing get() method.
API Note: The preferred alternative to the method get() is orElseThrow().
Example:
return Optional.ofNullable(fullName)
.map(n -> {
String[] names = n.split(" ");
return names[names.length-1];
})
.orElseThrow();
Var: Local-Variable Type Inference
For local variable declarations with initializers, enhanced for-loop indexes, and index variables declared in traditional for loops, allow the reserved type name var to be accepted in place of manifest types:
public class VarVariable {
//var x = 1; instance variable are not allowed
public List<Integer> getPairsNumbersBetweenOneAndFive
(/*var bigNumber could not infer the value from the arguments*/) {
// var g = null; cannot infer type for local
var list = new ArrayList<Integer>(); // infers ArrayList<Integer>
for (var i = 0; i < 5; i++) {
list.add(i);
}
// var var = x -> x % 2 == 0; could not infer lambda expression needs an explicit target-type
Predicate<Integer> var = x -> x % 2 == 0;
return list.stream().filter(var).collect(Collectors.toList());
}
}
If you would like to know more about Var: https://openjdk.org/jeps/286
If you want to know more about what's new in Java 10:
Java 11 (LTS)
This is an LTS version that has extended support until September 2026
New methods to String
Java 11 adds a few new methods to the String class: isBlank, lines, strip, stripLeading, stripTrailing, and repeat.
public String getAllItemsSeparateByComma(String shoppingCart) {
if (!shoppingCart.isBlank()) {
return shoppingCart
.lines() //Lines with Stream
.map(String::strip) //Returns a string whose value is this string, with all leading and trailing white space removed.
.collect(Collectors.joining(","));
}
return "";
}
New Methods to File
We can use the new readString and writeString static methods from the Files class
public static String readString(Path path);
public static Path writeString(Path path, CharSequence csq, OpenOption... options);
Predicate.not
Returns a predicate that is the negation of the supplied predicate. This is accomplished by returning the result of the calling target.negate().
return Stream.of(values)
.filter(Predicate.not(String::isBlank))
.collect(Collectors.toList());
HTTP Client (Standard)
The HTTP Client has been standardized in Java 11. As part of this work the previously incubating API, located in the jdk.incubator.http package, has been removed. At a very minimum, code that uses types from the jdk.incubator.http package will need to be updated to import the HTTP types from the standard package name, java.net.http.
The new HTTP API improves overall performance and provides support for both HTTP/1.1 and HTTP/2:
public Object getContentFromUrl(String url) throws IOException, InterruptedException {
HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(20))
.build();
HttpRequest httpRequest = HttpRequest.newBuilder()
.GET()
.uri(URI.create(url))
.build();
HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
return httpResponse.body();
}
PS: If you are using Java Modules, you will need this: requires java.net.http;
If you are eager to know more about what's new in Java 11: