代码之家  ›  专栏  ›  技术社区  ›  Alexander Mills

将映射的entryset表示为类型t

  •  0
  • Alexander Mills  · 技术社区  · 7 年前

    我需要将地图的每个条目表示为T类型,我不知道如何实现。

    entryset的定义如下:

    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>>)
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   TomáÅ¡ Záluský    7 年前

    你的 NeoEach.Each 方法接受 Iterable<T> 但您试图强制它使用 Map<Object,T> 是的。在我看来这有点模棱两可。这个方法应该怎么做 Map.Entry 好于 T 它自己?如果你使用地图键 Each 方法,在那里传递条目集而不是 Iterable 或通过 可迭代的 条目数:

    static <T, E> void Each(int limit, Iterable<Map.Entry<Object,T>> i, Asyncc.IEacher<T, E> m, Asyncc.IEachCallback<E> f) {
    

    在极端情况下,一些基于反射或代理的黑客可能会伪造 地图输入 看起来像 T型 但我相信这不是你我真正想要的。

    编辑: 编译给你的并不意味着它会运行。宣布未加工 Map 只是掩盖问题,解决不了问题。对待生态型的尝试 地图输入 因为值类型将在 ClassCastException 有时在未来。

        2
  •  1
  •   MC Emperor    7 年前

    您可以利用java streams api将每个条目转换为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 是的。