代码之家  ›  专栏  ›  技术社区  ›  Shervin Asgari

在Java泛型声明中使用“或”

  •  2
  • Shervin Asgari  · 技术社区  · 14 年前

    我有一个方法返回

    Map<String, List<Foo>> x();
    

    以及另一个返回

    Map<String, Collection<Foo>> y();
    

    现在,如果我想在我的字段中动态地添加一个这样的映射,那么如何编写使其工作的泛型呢?

    IE:

    public class Bar {
        private Map<String, ? extends Collection<Foo>> myMap;
    
        public void initializer() {
           if(notImportant) myMap = x(); //OK
           else myMap = y(); // !OK (Need cast to (Map<String, ? extends Collection<Foo>>)
        } 
    }
    

    现在我可以投签名了吗,即使 y() 是否声明为正在收集?

    如果不能进行强制转换,我可以用某种方式编写这个(集合或列表)吗? 我的意思是,列表是一个集合,所以它应该是可能的。

    private Map<String, Collection<Foo> | List<Foo>>> myMap;
    
    2 回复  |  直到 14 年前
        1
  •  3
  •   polygenelubricants    14 年前

    我不知道你的问题是什么。这段代码(基本上是您的代码)编译得很好。

    import java.util.*;
    public class Generic {
        static class Foo {};
        static Map<String, List<Foo>> x() {
            return null;
        }
        static Map<String, Collection<Foo>> y() {
            return null;
        }
        static Map<String, ? extends Collection<Foo>> myMap;
        public static void main(String[] args) {
            myMap = x();
            myMap = y();
            myMap = new HashMap<String,SortedSet<Foo>>();
            for (Collection<Foo> value : myMap.values());
        }
    }
    

    但是,你不能做这样的事 List<Integer|String> . Java泛型类型的界限并不是这样的。

        2
  •  4
  •   Andrei Fierbinteanu    14 年前

    你的方式 ? extends Collection 很好。你不能有类似的东西,如果你有,你就不知道是什么,如果你有,你会回来的。 myMap.get("someString") 你做不到 List|Collection someVariable = myMap.get("someString") ,您必须选择一个,如果您选择收藏,它与使用 ? extends ,如果您选择List,那么如果映射中的对象实际上是一个集合(也是一个集合),而不是一个列表,并且您尝试调用只有List具有的方法(如indexof),那么您将遇到各种各样的麻烦。至于你需要使用的原因 ?延伸 是因为 Map<String, List> 不延伸 Map<String, Collection> 即使列表扩展了集合。

    不过,你应该注意,使用 ?扩展集合 只允许您从映射中获取值,因为从中可以确定您得到的是一个集合(或集合的子集合),但如果您尝试将某些内容放入映射中,则无法(因为MyMap可能 Map<String, Set> 但是因为你只看到 Map<String, ? extends Collection> 你可以试着把一个不好的清单放进去)