HashMap 构造函数在传递两个流作为参数时无法推断参数

问题描述 投票:0回答:2

这是我在直播中的第一个方法。我正在尝试自己学习它,但由于它是一种新的编程风格,我遇到了困难。

问题

以下方法有一个

Map<Long, Ingredient>
参数(
Ingredient
具有 String 属性
name
)。

我想返回一个倒置的

Map<String, Long>
(字符串是类的属性“名称”
Ingredient
)。

我的工作for循环解决方案

public static Map<String, Long> focusOnNameAndInvert(Map<Long, Ingredient> articles) {
    ArrayList<String> nameList = new ArrayList<>(articles.values().stream().map(Ingredient::getName).collect(Collectors.toList()));
    ArrayList<Long> keyList = new ArrayList<>(articles.keySet());

    Map<String, Long> nameAndInvertedMap = new HashMap<>();
    for (int i = 0; i<nameList.size(); i++){
        nameAndInvertedMap.put(nameList.get(i), keyList.get(i));
    }

    return nameAndInvertedMap;
}

我的直播方法

初始化

<>
右侧的
HashMap
带有红色下划线,并显示 “无法推断参数”(使用 IntelliJ)

public static Map<String, Long> focusOnNameAndInvert(Map<Long, Ingredient> articles) {
    Map<String, Long> nameAndInvertedMap =  new HashMap<>(
            articles.values().stream().map(Ingredient::getName),
            articles.keySet().stream().map(articles::get));


    return nameAndInvertedMap;
}

为什么这没有按我预期的方式工作,我该如何解决它?

java dictionary hashmap java-stream
2个回答
1
投票

您的方法实际上并没有达到您希望的效果。从编译器错误中可以看出,没有

HashMap
构造函数接受
List
键和
List
值。此外,即使确实如此,您也会流式传输给定的
Map
(两次),然后尝试交换不同流中的键和值,最后甚至不收集流的值。流是延迟评估操作的管道,如果您不添加终端操作,它们甚至不会被执行。

这里有一个 Oracle 官方教程,很好地总结了流的概念及其工作原理:

https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html#laziness

您可以通过流式传输给定映射的条目来编写您的方法,然后使用

collect(Collectors.toMap())
终端操作收集它们,其中每个
Ingredient
的名称映射为键,而长键作为它们的值。

public static Map<String, Long> focusOnNameAndInvert(Map<Long, Ingredient> articles) {
    return articles.entrySet().stream()
            .collect(Collectors.toMap(entry -> entry.getValue().getName(), entry -> entry.getKey()));
}

请注意,如果有多个键(即您的情况下有重复的成分名称),则使用方法

toMap()
的 2 个参数版本收集条目将不起作用。该方法的 3 个参数版本应该是首选,因为它允许处理冲突键的情况(多个相同的键映射不同的值)。可能的实现可能是:丢弃一个值而不是另一个值,对这些值求和等等。

这是一种可能的实现,其中仅维护两个值之一。

public static Map<String, Long> focusOnNameAndInvert(Map<Long, Ingredient> articles) {
        return articles.entrySet().stream()
                .collect(Collectors.toMap(entry -> entry.getValue().getName(), entry -> entry.getKey(), (longVal1, longVal2) -> longVal1));
    }

0
投票

您的直播不正确。应该是这样的:

public static Map<String, Long> focusOnNameAndInvert(Map<Long, Ingredient> articles) {
  return articles.entrySet().stream()
      .collect(Collectors.toMap(entry -> entry.getValue().getName(), Map.Entry::getKey));
}
© www.soinside.com 2019 - 2024. All rights reserved.