java - Java 通用问题:无法转换 Map到 M 扩展地图
问题描述
在尝试编写一些通用代码时,我遇到了一个问题。当然,我找到了一些解决方法,但是,为什么下面的代码不起作用?
private static <K, U, M extends Map<K, U>>
Supplier<M> mapSupplier() {
return HashMap::new;
}
这返回
Error:(25, 17) java: incompatible types: bad return type in lambda expression
no instance(s) of type variable(s) K,V exist so that java.util.HashMap<K,V> conforms to M
更新:我需要这个地图供应商来创建自定义地图收集器:
public static <E, K, V, M extends Map<K, V>>
Collector<E, ?, M> collectToHashMapWithRandomMerge(BiConsumer<M, E> accumulator) {
return Collector.of(mapSupplier(),
accumulator,
TjiCollectionUtils.randomMapMerger());
}
使用HashMap::new调用Collector.of也会导致相同的编译错误
理想情况下,我不想创建额外的方法参数,只使用以下内容:
public static <E, K, V, M extends Map<K, V>>
Collector<E, ?, M> collectToHashMapWithRandomMerge(BiConsumer<M, E> accumulator) {
return Collector.of(HashMap::new,
accumulator,
TjiCollectionUtils.randomMapMerger());
}
我最终做出的答案:
public static <E, K, V>
Collector<E, ?, Map<K, V>> collectToMapWithRandomMerge(BiConsumer<Map<K, V>, E> accumulator) {
return Collector.of(HashMap::new,
accumulator,
TjiCollectionUtils.randomMapMerger());
}
它的调用方式如下:
MyCollectionUtils.collectToMapWithRandomMerge(
(Map<String,Integer> m, SomeClassToExtractFrom e) -> ...);
解决方案
这似乎是对泛型的一个常见误解,即被调用者决定泛型参数的类型。事实上,调用者确实如此。
谁打电话来mapSupplier
决定什么K
,是什么。假设我正在调用它,我想成为,成为,成为。这是有效的,因为实现.U
M
K
Integer
U
String
M
Hashtable<Integer, String>
Hashtable
Map
Supplier<Hashtable<Integer, String>> htSupplier = mapSupplier();
Hashtable<Integer, String> ht = htSupplier.get();
作为调用者,我希望上述内容能够正常工作,但是htSupplier.get
,通过您的实现,实际上会给我一个,这是一个与(就继承层次结构而言)HashMap<Integer, String>
无关的类型。Hashtable
换句话说,mapSupplier
单枪匹马地决定M
应该HashMap<K, U>
同时还说它将适用于任何M
实现Map<K, U>
。
每当您看到自己编写一个“通用”方法来决定其通用参数是什么时,该方法可能不应该具有该通用参数。因此,mapSupplier
应该很可能在没有M
参数的情况下重写:
private static <K, U>
Supplier<HashMap<K, U>> mapSupplier() {
return HashMap::new;
}
编辑:
看到来电者,我认为您可以:
- 也删除
M
,collectToHashMapWithRandomMerge
或者: - make
collectToHashMapWithRandomMerge
accept aSupplier<M>
,以便它的调用者可以决定地图的类型。
推荐阅读
- r - 当向量的长度发生变化时如何遍历向量?
- c# - 这个“工具”是什么以及如何禁用它?
- html - 在常规表格中,有没有办法在表格上放置外边框并省略表格标题?
- php - 登录后如何将一个opencart站点的用户重定向到另一个opencart站点?
- vb.net - 将 VBA SAPGUI 代码转换为 VB.NET 时遇到问题,找不到正确的导入库
- python - 尝试将输入字符串转换为浮点数时引发意外异常
- mongodb - 带有sails await 函数的多个聚合函数不会返回结果值
- mapbox-gl-js - 有没有办法动态设置地图弹出的高度?
- reactjs - 身份验证失败时重定向到登录
- javascript - 在代码沙箱内路由,由于 withRouter 而失败