【问题标题】:Convert an array of numbers to Map using Java Streams [duplicate]使用Java Streams将数字数组转换为Map [重复]
【发布时间】:2020-07-08 17:24:18
【问题描述】:

我在 Java 中有以下数组:

int arr[] = {4,5,6};

我想将它转换为java.util.Map<K,V> 实例,该实例将数组的索引作为键,将索引处的值作为映射的值。像这样,

0 = 4
1 = 5
2 = 6

我尝试了以下方法:

IntStream.range(0, arr.length)
                 .collect(Collectors.toMap(k -> k, k -> arr[k]));

但这会导致编译错误,例如:

Type mismatch: cannot convert from Collector<Object,capture#1-of ?,Map<Object,Object>> to Supplier<R>

The method collect(Supplier<R>, ObjIntConsumer<R>, BiConsumer<R,R>) in the type IntStream is not applicable for the arguments (Collector<Object,?,Map<Object,Object>>)

我在这里做错了什么?

我只是检查所有索引,然后将它们映射到我哪里出错的键和值?

【问题讨论】:

标签: java collections java-8 java-stream


【解决方案1】:

试试:

int arr[] = {4,5,6};
Map<Integer, Integer> resultMap = IntStream.range(0, arr.length).boxed()
                    .collect(Collectors.toMap(Function.identity(), k -> arr[k]));
resultMap.entrySet().forEach(entry -> System.out.println(entry.getKey() + " = " + entry.getValue()));

输出:

0 = 4
1 = 5
2 = 6

【讨论】:

  • Integer#valueOf 不是必需的。
  • @Jason 谢谢,我已经更新了答案
  • 不用担心,也可以不使用 k -> k 你可以只使用 Function#identity 来使用 Stream 的输入值和地图的键。
  • @NitinBisht Function.identity() 是什么?
  • @ng.newbie Function.identity() 返回一个始终返回其输入参数的函数。
【解决方案2】:

您正在使用未装箱的 IntStream。您需要使用.boxed()

如果你的数组是有序的,你可以这样做:

int arr[] = {4,5,6};

Map<Integer, Integer> map = Arrays.stream(arr).boxed()
    .collect(Collectors.toMap(i -> Arrays.binarySearch(arr, i), Function.identity()));

map.entrySet().forEach(entry -> System.out.println(entry.getKey() + " = " + entry.getValue()));

如果没有订购,您可以这样做:

Map<Integer, Integer> map = IntStream.range(0, arr.length).boxed()
        .collect(Collectors.toMap(Function.identity(), i -> arr[i]));

【讨论】:

  • 什么是Function.identity() ??
  • 类似于 i -> i(但不一样)。来自 javadoc:“返回一个始终返回其输入参数的函数。”。如果您想了解更多信息,请尝试以下答案:stackoverflow.com/questions/28032827/…
【解决方案3】:

您必须将 IntStream 装箱并使用 groupingBy 值来获得所需的计数。

试试这个:

Map<Integer, Long> map = Arrays
        .stream(arr)
        .boxed()
        .collect(Collectors.groupingBy(e -> e, Collectors.counting()));

【讨论】:

    【解决方案4】:

    有多种解决方案。

    1. For-each 循环

    Map<Integer, Integer> map = new HashMap<>();
    for (int i=0; i<arr.length; i++) {
        map.put(i, arr[i]);
    }
    

    在我看来,这在可读性方面是最清楚的。


    2。 IntStream 具有数组长度范围

    Map<Integer, Integer> map = IntStream.range(0, arr.length)
        .boxed()
        .collect(Collectors.toMap(Function.identity(), i -> arr[i]));
    

    这似乎是您最初的尝试。您需要将boxed()Stream&lt;Integer&gt; 绑定,以便将collect 与单个Collector 一起使用。


    3. Stream::iterateStream::limit

    Map<Integer, Integer> map = Stream.iterate(0, i -> i+1)
        .limit(arr.length)
        .collect(Collectors.toMap(Function.identity(), i -> arr[i]));
    

    这是一个简单的无限生成递增序列,该序列受数组长度的限制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-26
      • 2016-10-31
      • 1970-01-01
      • 2021-02-23
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多