问题
I have a MultivaluedMap
and a list of strings, and I would like to see which of those string are keys in the MultivaluedMap
. For each of the strings that are keys in the MultivaluedMap
, I want to construct a new Thing
out of the value of that key, set that string as a new key in a new HashMap<String, Thing>
, and set the new Thing
I've created as the value for that new key in the HashMap
.
Right now, using a vanilla forEach
, I have the following working solution:
MultivaluedMap<String, String> params = uriInfo.getQueryParameters();
HashMap<String, Thing> result = new HashMap<String, Thing>();
listOfStrings.forEach( (key) -> {
String value = params.getFirst(key);
if (value != null && !value.isEmpty()) {
result.put(key, new Thing(value));
}
});
However, I would like to implement a functional solution to this using the Java Stream API, and have attempted a fews solution. I have the following, which looks like it should work, but it does not:
MultivaluedMap<String, String> params = uriInfo.getQueryParameters();
HashMap<String, Thing> result = listOfStrings
.stream()
.filter(params::containsKey)
.map( e -> new AbstractMap.SimpleEntry<String, Thing>(e, new Thing(params.getFirst(e))))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
The Entry::getKey
and Entry::getValue
are giving a "Non-static method cannot be referred from a static context". I've tried other variations of this: constructing the objects in keyMapper
and valueMapper
lambdas, and using reduce with an empty map as the initial value. None have worked.
How would I rewrite my first, working solution using the Java Stream API and aggregation (e.g. collect
, reduce
)? I have referenced this post and this post and this post.
回答1:
Your code is fine. You just need to change the return type to Map
instead of HashMap
. If you need it to be HashMap
specifically, you can pass HashMap::new
into the factory overload.
One improvement I'd make is to cut out the unnecessary map()
operation and do the lookup in the collector:
Map<String, Thing> result = listOfStrings
.stream()
.filter(params::containsKey)
.collect(Collectors.toMap(Function.identity(), k -> new Thing(params.getFirst(k))));
来源:https://stackoverflow.com/questions/45826117/aggregate-liststring-into-hashmapstring-t-using-stream-api