如何使用 Java 流将两个数组合并到一个映射中?
Posted
技术标签:
【中文标题】如何使用 Java 流将两个数组合并到一个映射中?【英文标题】:How to merge two arrays into a map using Java streams? 【发布时间】:2018-04-07 11:29:19 【问题描述】:假设我们得到了以下两个数组
String[] keys = new String[] "a", "b", "c", "aa", "d", "b"
int[] values = new int[] 1 , 2 , 3 , 4 , 5 , 6
通过将这 2 个数组合并到 HashTable 中,我们得到以下内容
// pseudo-code
Map<String, Integer> dictionary = new HashTable<>(
("a" => 1)
("b" => 8) // because "b" appeared in index 1 and 5
("c" => 3)
("aa" => 4)
("d" => 5)
);
我们如何使用 java Lambda 风格做到这一点?
到目前为止,我有以下内容:
// this loops through the range given (used for index start and end)
// and sums the values of duplicated keys
tree.listMap = IntStream.range(range[0], range[1]).boxed().collect(
Collectors.toMap(i - > dictionary[i], i - > i + 1, Integer::sum, TreeMap::new)
);
但是,我想取 2 个数组,按键和值合并它们,其中值是重复键的所有值的总和。我们该怎么做?
【问题讨论】:
【参考方案1】:我不喜欢在引用索引时使用流,但您可以使用 groupingBy
和 summingInt
来完成此操作:
Map<String, Integer> result = IntStream.range(0, keys.length)
.boxed()
.collect(
Collectors.groupingBy(
i -> keys[i],
Collectors.summingInt(i -> values[i])
)
);
请注意,这是在键和值长度相等的假设下工作的,因此您可能需要进行一些额外的验证。
【讨论】:
我没有过多关注已排序的地图。要求只是将具有给定值的两个数组合并为重复键的总和。我的问题是不是太含糊了?让我知道,我会编辑。不管迈克尔,我很感激你的回答。学习新东西非常温暖:) @Jamie Nope,您的问题非常清楚。乐于助人。【参考方案2】:你去吧:
Map<String,Integer> themap =
IntStream.range (0, keys.length).boxed()
.collect (Collectors.toMap(i->keys[i],
i->values[i],
Integer::sum,
TreeMap::new));
输出:
a=1, aa=4, b=8, c=3, d=5
这与您发布的 sn-p 非常相似,但由于某种原因,您发布的 sn-p 不包含对 keys
和 values
数组的引用。
【讨论】:
this和this的输出略有不同。只是想知道,groupingBy
是否也对数据进行排序?
@nullpointer Map
不保证迭代顺序,因此输出的所有意图和目的都相同。
@nullpointer 我的答案返回一个TreeMap
(如在 OPs 代码中),因此对键进行了排序。您还可以修改groupingBy
解决方案以返回TreeMap
(默认情况下,当前实现返回HashMap
)。
感谢 Eran 的回答。我有点纠结于如何合并 2 个单独的数组。因此,为什么您看不到任何键和值的引用。在您的解决方案之前,我只获得了一个数组。以上是关于如何使用 Java 流将两个数组合并到一个映射中?的主要内容,如果未能解决你的问题,请参考以下文章
88. Merge Sorted Arrayleetcode算法,java将两个有序数组合并到一个数组中