将Map的条目集表示为T类型

时间:2019-02-22 22:28:32

标签: java

我需要将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>>)

2 个答案:

答案 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