问题
I have a map of the format (reference to Finding average using Lambda (Double stored as String))
Map<String, Double> averages=mapOfIndicators.values().stream()
.flatMap(Collection::stream)
.filter(objectDTO -> !objectDTO.getNewIndex().isEmpty())
.collect(Collectors.groupingBy(ObjectDTO::getCountryName,
Collectors.mapping(ObjectDTO::getNewIndex,
Collectors.averagingDouble(Double::parseDouble))));
I would like to ignore the ignore the entire country mapping even if one of them is newIndex value for that country is empty?
回答1:
Since Collectors.groupingBy
does not allow to skip groups, you either have to analyze the filtering condition in advance so you can filter before performing groupBy
or filter the map afterwards (I ignore the third option, implement your own groupingBy
collector.
Analyze in advance:
Map<String, Boolean> hasEmpty=mapOfIndicators.values().stream() .flatMap(Collection::stream) .collect(Collectors.groupingBy(ObjectDTO::getCountryName, Collectors.mapping(o->o.getNewIndex().isEmpty(), Collectors.reducing(false, Boolean::logicalOr)))); Map<String, Double> averages=mapOfIndicators.values().stream() .flatMap(Collection::stream) .filter(objectDTO -> !hasEmpty.get(objectDTO.getCountryName())) .collect(Collectors.groupingBy(ObjectDTO::getCountryName, Collectors.mapping(ObjectDTO::getNewIndex, Collectors.averagingDouble(Double::parseDouble))));
Filter the result:
Map<String, Double> averages=mapOfIndicators.values().stream() .flatMap(Collection::stream) .collect(Collectors.collectingAndThen( Collectors.groupingBy(ObjectDTO::getCountryName, Collectors.mapping(ObjectDTO::getNewIndex, Collectors.averagingDouble( s->s.isEmpty()? Double.NaN: Double.parseDouble(s)))), m->{ m.values().removeIf(d->Double.isNaN(d)); return m; }));
来源:https://stackoverflow.com/questions/25869821/java-lambda-filter-criteria-to-ignore-adding-to-map