在 Java 8 中使用 Lambda 将流收集到 HashMap 中

2022-09-01 03:45:49

我有一个HashMap,我需要使用一些函数进行过滤:

HashMap<Set<Integer>, Double> container
Map.Entry<Set<Integer>, Double> map = container.entrySet()
            .stream()
            .filter(k -> k.getKey().size() == size)

对于大小 = 2,以下各项应有效:

containerBeforeFilter = {1,2,3} -> 1.5, {1,2} -> 1.3
containerAfterFilter = {1,2} -> 1.3

在过滤器中应用函数后,我想再次将结果收集到哈希映射中。但是,当我尝试应用此处建议的方法时,我得到了非法语句。

因此,在筛选器之后应用的以下语句是非法的:

.collect(Collectors.toMap((entry) -> entry.getKey(), (entry) -> entry.getValue()));

收集未更改的映射值的正确方法是什么,其中唯一的标准是满足某些键?

更新

上述代码中的错误是变量的声明类型。它应该是而不是.mapMapMap.Entry

所以现在的功能代码是:

Map<Set<Integer>, Double> map = container.entrySet()
            .stream()
            .filter(k -> k.getKey().size() == size)
            .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue()));

答案 1

如果你的结束地图有“重复键”的机会,有更好的解决方案使用

toMap(Function<? super T, ? extends K> keyMapper,
                            Function<? super T, ? extends U> valueMapper,
                            BinaryOperator<U> mergeFunction,
                            Supplier<M> mapSupplier)

你可以这样使用它:

HashMap<Set<Integer>, Double> map = container.entrySet()
    .stream()
    .filter(k -> k.getKey().size() == size)
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (prev, next) -> next, HashMap::new));

然后,当添加重复的键时,它将使用最新的键,而不是引发异常。最后一个参数是可选的。

如果要将重复的键保留在列表中,请改用。Collectors.groupingBy


答案 2

似乎没有选择示例中的 类型参数,只返回一个 .Collectors.toMapstream.collectMap<Object,Object>

作为一种解决方法,您可以自己创建结果映射,并在上一个流步骤中将过滤后的条目添加到结果映射中:

Map<Set<Integer>, Double> result = new HashMap<>();
container.entrySet()
    .stream()
    .filter(entry -> entry.getKey().size() == size)
    .forEach(entry -> result.put(entry.getKey(), entry.getValue()));