使用 Stream API 将 List<String> 聚合到 HashMap<String, T>

Aggregate List<String> into HashMap<String, T> using Stream API

我有一个 MultivaluedMap 和一个字符串列表,我想看看这些字符串中的哪些是 MultivaluedMap 中的键。对于 MultivaluedMap 中作为键的每个字符串,我想从该键的值构造一个新的 Thing,将该字符串设置为新 HashMap<String, Thing> 中的新键,并将我创建的新 Thing 设置为 HashMap.

中新键的值

现在,使用香草 forEach,我有以下可行的解决方案:

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));
    }
});

但是,我想使用 Java 流 API 实现一个功能解决方案,并尝试了一些解决方案。我有以下内容,看起来应该可以,但没有:

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));

Entry::getKeyEntry::getValue 给出了“无法从静态上下文引用非静态方法”。我已经尝试过其他变体:在 keyMappervalueMapper lambdas 中构造对象,并使用带有空映射的 reduce 作为初始值。 None 成功了。

我如何使用 Java 流 API 和聚合(例如 collectreduce)重写我的第一个可行解决方案?我引用了 this post and this post and this post.

你的代码没问题。您只需要将 return 类型更改为 Map 而不是 HashMap。如果你需要它是 HashMap 具体来说,你可以将 HashMap::new 传递到 factory overload.

我要做的一项改进是删除不必要的 map() 操作并在收集器中进行查找:

Map<String, Thing> result = listOfStrings
        .stream()
        .filter(params::containsKey)
        .collect(Collectors.toMap(Function.identity(), k -> new Thing(params.getFirst(k))));