Unlock Java 9‑16: New APIs, Immutable Collections, and Stream Enhancements
This article introduces Java 9‑16 features such as factory methods for immutable collections, Optional.ifPresentOrElse, new Stream operations like takeWhile/dropWhile and toList, plus enhanced Duration and LocalDate utilities, providing concise, modern code patterns for developers.
People often stick to long‑tested Java 7/8, but this article introduces useful new APIs from Java 9‑13.
Java 9 added factory methods for immutable collections:
List.of(E... elements)
Set.of(E... elements)
Map.ofEntries(Entry<? extends K, ? extends V>... entries)
Previously you had to create a mutable list and wrap it with Collections.unmodifiableList:
List<String> list = new ArrayList<>();
list.add("abc");
list.add("xyz");
Collections.unmodifiableList(list);Now you can do it in one line:
List.of("abc","xyz");Java 9 also introduced Optional.ifPresentOrElse to reduce boilerplate:
Optional<Email> mail = ...;
if (mail.isPresent()) {
send(mail.get());
} else {
reportError();
}It can be rewritten more flexibly:
mail.ifPresentOrElse(
m -> send(m),
() -> reportError()
);Further improvement with Optional.or:
Optional<String> optional = Optional.<String>ofNullable("first")
.or(() -> Optional.of("second"));Optional can produce a Stream directly:
Optional.of(obj).stream();Compared to the older pattern:
Optional.of(obj).map(Stream::of).orElse(Stream.empty());Stream interface gained new methods in later versions:
default Stream<T> takeWhile(Predicate<? super T> predicate)
default Stream<T> dropWhile(Predicate<? super T> predicate)These allow predicate‑based limiting or skipping of elements.
Example using IntStream.iterate with a predicate:
IntStream.iterate(1, i -> i < 16, i -> i + 1)
.forEach(System.out::println);Equivalent to the older two‑step approach:
IntStream.iterate(1, i -> i + 1)
.takeWhile(i -> i < 16)
.forEach(System.out::println);Java 16 introduced Stream.toList() which is more convenient and performant than collect(Collectors.toList()):
collection.stream()
.toList();Java.time got more utilities; Duration can now provide parts directly:
Duration dur = Duration.between(now().minusDays(10).minusSeconds(567), now());
System.out.println(dur.toDaysPart()); // 10
System.out.println(dur.toMinutesPart()); // 9Duration also supports division and creation with ChronoUnit:
Duration dur = Duration.of(3, ChronoUnit.HOURS);
Duration ans = dur.dividedBy(Duration.of(20, ChronoUnit.MINUTES));
System.out.println(ans); // 9LocalDate now has datesUntil to produce a stream of dates between two dates:
Stream<LocalDate> dates = LocalDate.of(2021,3,3)
.datesUntil(LocalDate.of(2021,10,9));21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
