As an aside, if you want to see how different JDK versions differ and what apis have been added or removed, you can check out this link:
- Javaalmanac. IO/JDK / 17 / apid…
The two versions in the path are the two versions to be compared, and their interfaces are as follows:
We can also use the JDK built-in JDEPS tool to find expired and deprecated apis and their replacements
jdeps --jdk-internals -R --class-path 'libs/*' $project
Copy the code
Libs is the directory where all your dependencies are located, and $project is your project jar package.
. JDK Internal API Suggested Replacement ---------------- --------------------- sun.misc.BASE64Encoder Use Java.util.base64 @since 1.8 Sun.reflect.Reflection Use Java.lang.StackWalker @since 9Copy the code
There are two updates to the Stream API in Java 16:
MapMulti and toList apis have been added.
mapMulti
MapMulti is essentially a complement to the existing flatMap which is not suitable for use in certain scenarios. FlatMap is used to map an object to multiple objects and then continue Stream, for example, taking each number in List
> and converting it to a new List
:
integerLists.stream().flatMap(integers -> integers.stream()).collect(Collectors.toList());
Copy the code
This is great for scenarios where each element is itself a collection type. Let’s look at another example. Suppose we have the mail Record class, which contains the ID, and the email to which it was sent and the email to which it was cc:
record Mail(int id, Set<String> sendTo, Set<String> cc) {}
Copy the code
We want to find all the different contacts for a batch of emails and put them in a List, maybe something like this:
Set<String> collect = mails.stream().flatMap(mail -> {
Set<String> result = new HashSet<>();
result.addAll(mail.sendTo());
result.addAll(mail.cc());
return result.stream();
}).collect(Collectors.toSet());
Copy the code
However, it is not elegant to create an extra Set and corresponding Stream for each Mail, and pass through sendTo and cc twice for each Mail (addAll once, Stream again). In fact, we are currently just taking cc and sendTo out of mail and participating in the subsequent Stream. In this scenario, mapMulti is a good fit:
Set<String> collect = mails.stream().<String>mapMulti((mail, consumer) -> {
mail.cc().forEach(consumer::accept);
mail.sendTo().forEach(consumer::accept);
}).collect(Collectors.toSet());
Copy the code
As can be seen:
- The input parameter to mapMulti is one
BiConsumer
In fact, it isUse the consumer in its argument to receive objects that follow the Stream - The idea behind mapMulti is to continue the Stream by passing the object in the argument that needs to participate in the subsequent Stream to the consumer
- consumer There are no restrictions on object typesTo restrict, you must take a parameter
<String>
Otherwise, the final return isSet<Object>
Rather thanSet<String>
If mail sendTo and CC need to be retrieved from other places, mapMulti can also implement:
Set<String> collect = mailIds.stream().<String>mapMulti((mailId, consumer) -> {
mailService.getCCById(mailId).forEach(consumer::accept);
mailService.getSendToById(mailId).forEach(consumer::accept);
}).collect(Collectors.toSet());
Copy the code
There are also some interesting uses, such as converting a List of mixed types to a unified type:
class C { static void expandIterable(Object e, Consumer<Object> c) { if (e instanceof Iterable<? > elements) { for (Object ie : elements) { expandIterable(ie, c); } } else if (e ! = null) { c.accept(e); } } public static void main(String[] args) { var nestedList = List.of(1, List.of(2, List.of(3, 4)), 5); Stream<Object> expandedStream = nestedList.stream().mapMulti(C::expandIterable); }}Copy the code
Use Optional. IfPresent (Consumer
action)
Stream.of(Optional.of("0"), Optional.of("1"), Optional.empty())
.mapMulti(Optional::ifPresent)
.forEach(System.out::print);
Copy the code
toList
For Stream, toList is directly converted into List. Since truncation operation in COLLECT is not involved, it occupies less memory and requires fewer and faster operations than COLLECT.
Before converting it to a List, you need to collect(Collectors. ToList ()). The generated List is an ArrayList and can be mutable
However, the new Api toList generates is UnmodifiableList, which is immutable.
So these two apis cannot be replaced directly with each other, and you need to do some checking to make sure there are no changes.
Wechat search “my programming meow” public account, a daily brush, easy to improve skills, won a variety of offers: