如何使用Java Stream API将数组转换为HashMap

3

我试图做一些相当简单的事情,但是编译失败了,我无法理解是谁出了问题

我有一个标题列表,我需要将其转换为Map<Index,String>,其中键(索引)和值是标题名称

我知道如何使用for each来实现它,但我想要在Collectors.to map中拥有它,任何帮助将不胜感激

final String[] headerDisplayName = getHeaderDisplayName(harmonizationComponentDataFixRequest);

IntStream.of(0, headerDisplayName.length).collect(Collectors.toMap(Function.identity(), index-> headerDisplayName[index]));

1
IntStream 没有 #collect(Collector) 方法。 - Slaw
请查看此链接: one - gowridev
2个回答

5
您可以将range方法与IntStreamboxed方法结合使用。
(当您像示例中使用of方法时,此流中仅包含0和数组的大小。此外,这将导致ArrayIndexOutOfBoundsException
可能的解决方案如下所示(range方法的第一个参数被包括在内,第二个参数被排除在外)。
Map<Integer, String> map = IntStream.range(0, headerDisplayName.length)
        .boxed()
        .collect(Collectors.toMap(
                Function.identity(), 
                i -> headerDisplayName[i])
        );

要了解为什么boxed()能够解决这个问题,请查看我在此问题的答案 - Lavish Kothari

2

在@csalmhof的回答上补充一点,我认为这里需要解释一下为什么使用boxed方法是有效的。

如果您不使用boxed()方法,而只是简单地编写以下内容:

Map<Integer, String> map = IntStream.range(0, headerDisplayName.length)
        .collect(Collectors.toMap(
                Function.identity(),
                index -> headerDisplayName[index])
        );

Java需要将index作为Object类型处理,没有隐式转换可用,因此会出现错误。

但是,如果像以下代码中那样使用boxed(),则不会出现错误:

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

您之所以没有在这里得到错误,是因为Java将index解释为一个Integer,并且从Integerint进行了隐式转换。一个好的IDE可以帮助你解释这种类型的问题。在IntelliJ中,如果您按下ctrl+space并将光标放在index上(启用Eclipse键映射),则会得到以下结果,不需要使用boxed()

enter image description here

当您使用了boxed()后,您将得到以下结果。 enter image description here

我希望这能澄清为什么使用boxed()可以避免编译错误。此外,您可以在将来使用此方法查找lambda参数的实际类型,这在某些情况下可能很有用(其中一种情况是OP指出的情况)。


@BarakKedem 基本错误是没有 IntStream#collect(Collector) 方法。不过,确实有一个 Stream#collect(Collector)方法,这就是为什么调用 IntStream#boxed() 可以正常工作的原因,因为它返回了一个 Stream<Integer>。在此答案中显示的 IDE 错误是“混淆”的,可能是由于存在 IntStream#collect(Supplier,ObjIntConsumer,BiConsumer) 方法。所以编译器看到确实有一个名为 collect 的方法,然后继续尝试解析传递给该方法的参数。但由于您正在创建一个 Collector,所以存在问题,它... - Slaw
无法推断泛型类型。因此,对于 toMap,它默认为 Object,这意味着它推断参数为 Function<Object, Object>。这使得 index 成为一个 Object,因此在尝试使用它来访问数组元素时出现错误。但是,如果你只是将 index -> headerDisplayName[index] 更改为 (Integer index) -> headerDisplayName[index],那么代码的这部分就会开始工作。然后你会发现底层错误是尝试将 Collector 传递给 IntStream#collect(Supplier,ObjIntStream,BiConsumer) 方法。 - Slaw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接