我需要将Map的每个条目都表示为T类型,但我不知道该怎么做。
这是条目集的定义:
public Set<Map.Entry<K,V>> entrySet()
所以我需要这样的东西:
Map<?,?> -> Set<T>
这将编译:
public static <T, E> void Each(Map i, IEacher<T, E> m, Asyncc.IEachCallback<E> f) {
NeoEach.Each(Integer.MAX_VALUE, i.<T>entrySet(), m, f);
}
但我收到警告:
未经检查的分配:“ java.util.Set”为“ java.lang.Iterable”。 原因:“ i”为原始类型,因此entrySet的结果被删除
但是奇怪的是,它将无法编译:
public static <T, E> void Each(Map<Object,Object> i, IEacher<T, E> m, Asyncc.IEachCallback<E> f) {
NeoEach.Each(Integer.MAX_VALUE, i.<T>entrySet(), m, f);
}
使用Map i
进行编译,但是Map<Object,Object> i
不会说:
预期:
i:java.lang.Iterable<T>
实际:
i.<T>entrySet() (java...java.lang.Object,java.lang.Object>>)
答案 0 :(得分:2)
您的NeoEach.Each
方法接受Iterable<T>
,但是您正试图强制其使用Map<Object,T>
的条目集。在我看来,这有点模棱两可。与Map.Entry
本身相比,该方法应该对T
做得更好?如果您在Each
方法中使用映射键,请在此处传递设置的条目而不是Iterable
或传递Iterable
条目:
static <T, E> void Each(int limit, Iterable<Map.Entry<Object,T>> i, Asyncc.IEacher<T, E> m, Asyncc.IEachCallback<E> f) {
在极端情况下,可能可以做一些反射或基于代理的黑客来伪造Map.Entry
看起来像T
,但我相信这不是您和我真正想要的。
编辑:
编译给您的内容并不意味着它会运行。声明原始Map
只会掩盖问题,而不能解决问题。将原始类型Map.Entry
视为值类型的尝试将在将来的ClassCastException
上失败。
答案 1 :(得分:1)
您可以利用Java Streams API将每个Entry转换为T,但是必须定义如何实现。然后,您可以传递一个转换函数以将其转换为T
。
public static <K, V, T> Set<T> transform(Map<K, V> map, Function<Map.Entry<K, V>, T> transformationFunction) {
return map.entrySet().stream()
.map(transformationFunction)
.collect(Collectors.toSet());
}
不能使用Map<Object, Object>
的原因是 generics are invariant 。