The requirement is to iterate over a list of Foo
s, and when 2 Foo
s have the same id
merge their list of input
s together and obtain a new object.
I have achieved this with 2 streams and a private method to do this:
import java.util.HashSet;
import java.util.Set;
class Foo {
private String id;
private Set<String> inputs = new HashSet<>();
String getId() {
return id;
}
void setId(String id) {
this.id = id;
}
Set<String> getInputs() {
return inputs;
}
}
and the GetMatchingFoos
class:
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
import java.util.List;
import java.util.Map;
public class GetMatchingFoos {
public List<Foo> call(List<Foo> matchedFoos) {
Map<String, List<Foo>> idToMatchedFooMap = matchedFoos.stream()
.collect(groupingBy(Foo::getId, toList()));
List<Foo> mergedAndMatchedFoos = idToMatchedFooMap.values().stream()
.map(this::mergeFoos)
.collect(toList());
return mergedAndMatchedFoos;
}
private Foo mergeFoos(List<Foo> matchedFoos) {
Foo result = new Foo();
for(Foo matchedFoo : matchedFoos) {
result.setId(matchedFoo.getId());
result.getInputs().addAll(matchedFoo.getInputs());
}
return result;
}
}
Can I obtain the same result by using only a single lambda operation that is more elegant than the above? I have looked into reducing
but it was not very trivial.