Reputation: 155
I want to generate a list of strings, comprising id and external ids, from a list of Bean.
public class User {
private String id;
private List<String> externalIds;
}
I got it using the below code, but here I need to do the stream twice.
List<User> references = new ArrayList();
Stream.concat(references.stream().map(User::getId),
references.stream().map(User::getExternalIds).flatMap(Collection::stream))
.collect(Collectors.toList());
Is there any better way to rewrite this code?
Upvotes: 1
Views: 3922
Reputation: 40057
If you're using Java 16+ you can do it using mapMulti
. This essentially intercepts each item in the stream and replaces it with other items. It avoids re-streaming and flatmapping. Since the nature of the stream(i.e. type) is being changed from User
to String
, the witness before mapMulti
is required.
user id
in the stream.external id
in the stream for that userList<String> results = references.stream()
.<String>mapMulti((user, consumer) -> {
consumer.accept(user.getId());
for (String id : user.getExternalIds()) {
consumer.accept(id);
}
}).toList();
Upvotes: 0
Reputation: 425398
Try this:
references.stream()
.flatMap(u -> Stream.of(List.of(u.getId()), u.getExternalIds()))
.flatMap(List::stream)
.collect(Collectors.toList());
Upvotes: 1
Reputation: 9175
Use Stream.concat
inside the flatMap
operation:
references.stream()
.flatMap(user -> Stream.concat(
Stream.of(user.getId()),
user.getExternalIds().stream()
))
.collect(Collectors.toList())
Upvotes: 8