I have a FootballTeam
class that contains Footballer
class. Using streams is it possible to get the FootballTeam
from a list of football teams if the FootballTeam
contains a Footballer
with a particular id
. Is it possible to do the below with streams. i.e Get both the targetFootballer
and targetTeam
;
FootballTeam targetTeam = null;
Footballer targetFootballer = null;
for(FootballTeam team : list.getFootballTeams()){
for(Footballer f : team.getFootballers()) {
if(f.getId() == 1){
targetFootballer = f;
break;
}
}
if(targetFootballer != null) {
targetTeam = team;
}
}
Don’t think in terms of loops, but rather what high-level operation you’re performing, e.g. finding the first element matching a criteria. The biggest obstacle for expressing such an operation, is that Java methods can not return two values. Using a Map.Entry
as a pair type holding both results, you can use
Map.Entry<FootballTeam,Footballer> target = list.getFootballTeams()
.stream()
.flatMap(team -> team.getFootballers()
.stream()
.filter(f -> f.getId() == 1)
.map(f -> new AbstractMap.SimpleImmutableEntry<>(team, f)))
.findFirst()
.orElse(null);
Since you’re likely want to perform a subsequent operation on these values, you might avoid storing the result in a variable and apply the operation directly, e.g.
list.getFootballTeams()
.stream()
.flatMap(team -> team.getFootballers()
.stream()
.filter(f -> f.getId() == 1)
.map(f -> new AbstractMap.SimpleImmutableEntry<>(team, f)))
.findFirst()
.ifPresent(e -> {
FootballTeam targetTeam = e.getKey();
Footballer targetFootballer = e.getValue();
// do your action
});
Here, the action is only executed if a match has been found and you don’t need explicit code dealing with absent values. In the first example, .orElse(null)
says that the target
should be null
if no match has been found, so you have to test for null
later-on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With