问题
I want to know how to extract a List<D>
from a HashMap<E,R>
considering these constraints:
E
is a custom class;R
is a custom class containing aSet<D>
of custom objects;
What I have tried: I tried addressing the issue in this question.
In that previous case, I had a simple Map<E,List<R>>
, but in this case I have to access the R
class which has the targeted Set<D>
.
What I want to do in the following portion of the code is to get the Elements of the Set<D>
whose country names are equal to the given parameter.
I have tried using the same solution :
Map<E,R> map = new HashMap<E,R>();
public List<D> method(String countryname) {
return map.values().stream().filter((x)->{
return x.getSet().stream().anyMatch((t) -> {
return t.getCountry().equals(countryname);
});
})
.map(R::getSet)
.flatMap(List::stream)
.collect(Collectors.toList()); //does not compile
}
// the R class
class R {
private Set<D> set = new TreeSet<D>();
//getters & setters & other attributes
}
回答1:
I believe the flatMap
step is wrong, since your map
step transforms your Stream<R>
to a Stream<Set<D>>
, so flatMap(List::stream)
should be flatMap(Set::stream)
:
return map.values()
.stream()
.filter(x -> x.getSet().stream().anyMatch(t -> t.getCountry().equals(countryname)))
.map(R::getSet)
.flatMap(Set::stream)
.collect(Collectors.toList());
Besides, as you can notice above, the code can be much more readable if you avoid using curly braces when you don't have to.
回答2:
In order to improve readability of your code I would suggest avoiding unnecessary curly braces in lambdas and even the lambdas themselves. Use method references where possible.
return map.values()
.stream()
.map(R::getSet)
.filter(set -> set.stream()
.map(R::getCountry)
.anyMatch(countryname::equals))
.flatMap(Set::stream)
.collect(toList());
The last flatMap
and collect
operations can be shortened to one line:
.collect(ArrayList::new, List::addAll, List::addAll);
Or if you're using Java 9:
.collect(flatMapping(Set::stream, toList()));
However it's just a matter of taste.
回答3:
get the Elements of the Set whose country names are equal to the given parameter.
You seem to be looking for
// input as parameter to the method for simplicity
public List<D> method(Map<E, R> map, String countryName) {
return map.values() // Collection<R>
.stream() // Stream<R>
.flatMap(a -> a.getSet().stream()) // Stream<D>
.filter(t -> t.getCountry().equals(countryName)) // filtered
.collect(Collectors.toList()); // collected to list
}
来源:https://stackoverflow.com/questions/54070685/how-to-extract-a-listd-from-a-hashmape-r-using-stream