简体   繁体   English

Java Stream 将列表中的元素映射到数字

[英]Java Stream Map elements in a list to a number

I have a int[] converted to a List<Integer> .我有一个int[]转换为List<Integer> The task at hand is to map each element of the set to 0. So I think of converting this List to a Set and then map to 0. So for a set 1, 3, 7, 4, 8 , it should look like: (1, 0), (3, 0), (7, 0), (4, 0), (8, 0) .手头的任务是将集合的每个元素映射到 0。所以我想到将这个List转换为一个Set ,然后映射到 0。所以对于集合1, 3, 7, 4, 8 ,它应该看起来像: (1, 0), (3, 0), (7, 0), (4, 0), (8, 0) To achieve this, I've tried:为了实现这一点,我尝试过:

Map<Integer, Integer> map = Arrays.stream(elements)
    .boxed()
    .collect(Collectors.toMap(x -> x, x -> 0));

But while trying this, I get this error:但是在尝试此操作时,我收到此错误:

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 0
    at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
    at java.util.HashMap.merge(HashMap.java:1254)
    at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
    at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
    at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250)
    at java.util.Spliterators$IntArraySpliterator.forEachRemaining(Spliterators.java:1032)
    at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at DeleteElementsByOccurence.main(DeleteElementsByOccurence.java:18)                  <-- Refers to the Collectors.toMap line

I know this stuff is super easy in Scala, but I am unable to figure out the logic to do in Java.我知道这些东西在 Scala 中非常容易,但我无法弄清楚在 Java 中要做的逻辑。

elements seem to contain duplicates. elements似乎包含重复项。 To deal with this, you can supply a third argument to toMap to say what you want to do when there are duplicates.为了解决这个问题,你可以为toMap提供第三个参数来toMap当有重复时你想做什么。 ( this overload ) 这个重载

.collect(Collectors.toMap(x -> x, x -> 0, (x, y) -> x));

x and y are the values corresponding to two duplicate keys, and you get to decide what the new value is for that key. xy是对应于两个重复键的,您可以决定该键的新值是什么。 Since in this case all the values are 0, there's not much of a choice, is there?因为在这种情况下所有值都是 0,所以没有太多选择,是吗?

You don't actually need to convert the array to a set first, because the third argument ( merger function) handles duplicates automatically.您实际上不需要先将数组转换为集合,因为第三个参数( merger函数)会自动处理重复项。

If your list contains duplicate keys, the map will throw an exception.如果您的列表包含重复的键,地图将抛出异常。 You can use distinct() to remove the duplicate keys.您可以使用distinct()删除重复的键。

int[] a = {1,3,7,4,4,8}; // 4 is duplicated

Map<Integer, Integer> map = Arrays.stream(a)
    .boxed()
    .distinct()   // added
    .collect(Collectors.toMap(x -> x, x -> 0));

Alternatively, pass a merge function或者,传递一个合并函数

Map<Integer, Integer> map = Arrays.stream(a)
    .boxed()
    .collect(Collectors.toMap(x -> x, x -> 0, (x, y) -> x));

(equally correct, identical merge functions: (x, y) -> y , (x, y) -> 0 ) (同样正确,相同的合并函数: (x, y) -> y , (x, y) -> 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM