在尝试编写一些通用代码时,我遇到了一个问题。当然,我找到了一些解决方法,但为什么下面的代码仍然不起作用?
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
更新: 我需要这个 map 供应商来创建自定义 map 收集器:
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
以及,或者: - 制作
collectToHashMapWithRandomMerge
接受Supplier<M>
,以便它的调用者可以决定 map 的类型。
关于Java 通用问题 : cannot cast Map<K, V> 到 M extends Map<K, V>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60263977/