gpt4 book ai didi

java - Collectors.groupingBy (Function, Supplier, Collector) 不接受 lambda/看不到流值

转载 作者:搜寻专家 更新时间:2023-11-01 01:48:54 28 4
gpt4 key购买 nike

我尝试使用流和收集器对值进行分组。我有我必须拆分的字符串列表。

我的数据:

List<String> stringList = new ArrayList<>();
stringList.add("Key:1,2,3")
stringList.add("Key:5,6,7")

Key 是 map 中的键,1,2,3 是 map 中的值

首先我尝试使用简单的toMap

Map<String, List<Integer>> outputKeyMap = stringList.stream()
.collect(Collectors.toMap(id -> id.split(":")[0],
id-> Arrays.stream(id.split(":")[1].split(",")).collect(Collectors.toList());

但它不起作用,因为它总是创建相同的 key 。所以我需要使用groupingBy函数。

Map<String, List<Integer>> outputKeyMap = stringList.stream().collect(groupingBy(id -> id.toString().split(":")[0],
TreeMap::new,
Collectors.mapping(id-> Arrays.stream(id.toString().split(":")[1].split(","))
.map(Integer::valueOf)
.collect(Collectors.toSet()))));

但在这个解决方案中,编译器看不到传递给 lambda 函数的值,我不明白为什么,因为 Function 是第一个参数,也传递给 Collectors.mapping。在此解决方案中,流不起作用。

Collectors.groupingBy (Function<? super T, ? extends K> classifier,
Supplier<M> mapFactory,
Collector<? super T, A, D> downstream)

编辑:为什么 groupingBy 函数不起作用

我忘记在 Collectors.mapping 中添加 Collectors.toSet() 作为第二个参数。但后来我收到了 Set in Set,所以这不是我要找的东西。应该使用 flatMapping 但它是在 Java9 中。

    Map<String, Set<Set<String>>> collect = stringList.stream()
.collect(groupingBy(id -> id.split(":")[0],
TreeMap::new,
Collectors.mapping(id-> Arrays.stream(id.toString().split(":")[1].split(","),
Collectors.toSet())

最佳答案

您必须使用 Collectors.toMap 的重载接受合并函数:

Map<String, List<Integer>> result = stringList.stream()
.map(string -> string.split(":"))
.collect(Collectors.toMap(
splitted -> splitted[0],
splitted -> Arrays.stream(splitted[1].split(","))
.map(Integer::valueOf)
.collect(Collectors.toCollection(ArrayList::new)),
(l1, l2) -> { l1.addAll(l2); return l1; }));

此处 (l1, l2) -> { l1.addAll(l2);返回l1; } 是合并函数。每当发生键冲突时,收集器都会调用它。由于 List.addAll 改变列表,我们需要确保创建的第一个列表是可变的,因此使用 .collect(Collectors.toCollection(ArrayList::new)) 在值映射函数中。

我还将第一次拆分优化为在收集之前调用的 Stream.map 操作,从而避免多次拆分。


上述解决方案不会从列表中删除重复项。如果你需要,你应该收集到 Set 而不是:

Map<String, Set<Integer>> result = stringList.stream()
.map(string -> string.split(":"))
.collect(Collectors.toMap(
splitted -> splitted[0],
splitted -> Arrays.stream(splitted[1].split(","))
.map(Integer::valueOf)
.collect(Collectors.toCollection(LinkedHashSet::new)),
(s1, s2) -> { s1.addAll(s2); return s1; }));

请注意,LinkedHashSet 保留了插入顺序。

关于java - Collectors.groupingBy (Function, Supplier, Collector) 不接受 lambda/看不到流值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54520174/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com