无法使用 :: 运算符将新列表初始化为 Map 的值?
Unable to initialize new List as value of a Map with the :: Operator?
在处理纸牌游戏项目时,我试图创建一个新地图,同时已经有了一个我想用作 KeySet 的列表。 Map 必须使用 Player 类型的 Keys,并且每个 Keys 都有一个由单个 List<Trick>
组成的 Value,Player 是一个 Interface 和 Trick - class.
最初我尝试使用我拥有的 List<Player> players
的 Stream,然后通过以下方式将其收集到 Map 中:
private Map<Player, List<Trick>> playerTricks = players.stream()
.collect(Collectors.toMap(x -> x, ArrayList::new));
我的IDE,IntelliJ,但是不允许我使用这种格式,正如它所说的那样"Cannot resolve Constructor ArrayList"。
令我惊讶的是,当我删除 ::
-Operator:
时 IDE 停止了抱怨
(Collectors.toMap(x -> x, x -> new ArrayList<Trick>()));
虽然我现在的代码没有异常,但我仍然不明白为什么范围解析运算符会产生这样的错误。如果有人能正确解释它,我将不胜感激。
P.S.
在搜索解决方案时,我发现了这个 Whosebug 线程:
Storing a new object as the value of a hashmap?
它确实涉及类似的问题,但并没有真正解决我面临的问题。
second parameter of Collectors.toMap
接受一个 Function
,它接受流类型并将其映射到新的 Map
的值类型。
Function<? super T,? extends U> valueMapper
首先,::
不像在 C++ 中那样被称为作用域解析运算符,尽管在 Java 中创建 方法引用 时它的功能有些相似.只是(简单地)"double-colon operator".
方法引用 ArrayList::new
与 Function<Player, List<Trick>>
不匹配,因为没有 ArrayList(Player)
构造函数。不能使用此方法参考。您试图忽略 Player
参数,但方法引用必须使用它。
当您将方法引用替换为 lambda 表达式 x -> new ArrayList<Trick>()
时,它确实匹配 Function<Player, List<Trick>>
。您正在使用 x
,它被隐式定义为 Player
,而 lambda 表达式的类型是 List<Trick>
,它匹配。您忽略了 lambda 表达式中的 Player
x
,甚至在它调用创建新的 ArrayList
.
之前
您的 lambda 表达式 不 等同于方法引用,因为您的方法引用试图找到一个 ArrayList(Player)
构造函数,而 lambda 表达式采用 Player
并在仅显式调用无参数 ArrayList
构造函数时忽略它。
在处理纸牌游戏项目时,我试图创建一个新地图,同时已经有了一个我想用作 KeySet 的列表。 Map 必须使用 Player 类型的 Keys,并且每个 Keys 都有一个由单个 List<Trick>
组成的 Value,Player 是一个 Interface 和 Trick - class.
最初我尝试使用我拥有的 List<Player> players
的 Stream,然后通过以下方式将其收集到 Map 中:
private Map<Player, List<Trick>> playerTricks = players.stream()
.collect(Collectors.toMap(x -> x, ArrayList::new));
我的IDE,IntelliJ,但是不允许我使用这种格式,正如它所说的那样"Cannot resolve Constructor ArrayList"。
令我惊讶的是,当我删除 ::
-Operator:
(Collectors.toMap(x -> x, x -> new ArrayList<Trick>()));
虽然我现在的代码没有异常,但我仍然不明白为什么范围解析运算符会产生这样的错误。如果有人能正确解释它,我将不胜感激。
P.S. 在搜索解决方案时,我发现了这个 Whosebug 线程:
Storing a new object as the value of a hashmap?
它确实涉及类似的问题,但并没有真正解决我面临的问题。
second parameter of Collectors.toMap
接受一个 Function
,它接受流类型并将其映射到新的 Map
的值类型。
Function<? super T,? extends U> valueMapper
首先,::
不像在 C++ 中那样被称为作用域解析运算符,尽管在 Java 中创建 方法引用 时它的功能有些相似.只是(简单地)"double-colon operator".
方法引用 ArrayList::new
与 Function<Player, List<Trick>>
不匹配,因为没有 ArrayList(Player)
构造函数。不能使用此方法参考。您试图忽略 Player
参数,但方法引用必须使用它。
当您将方法引用替换为 lambda 表达式 x -> new ArrayList<Trick>()
时,它确实匹配 Function<Player, List<Trick>>
。您正在使用 x
,它被隐式定义为 Player
,而 lambda 表达式的类型是 List<Trick>
,它匹配。您忽略了 lambda 表达式中的 Player
x
,甚至在它调用创建新的 ArrayList
.
您的 lambda 表达式 不 等同于方法引用,因为您的方法引用试图找到一个 ArrayList(Player)
构造函数,而 lambda 表达式采用 Player
并在仅显式调用无参数 ArrayList
构造函数时忽略它。