有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java集合对元素的多态访问

我有一个LinkedHashSet此类型的值。 此类型正在实现接口该类型

我需要这个集合的多态性使用——能够将它指向LinkedHashSet<;那种类型>

这是怎么做到的

我知道这是一个幼稚的问题,但我尝试过的几件事都没有成功,我想用正确的方式去做

提前谢谢

//==============================

更新:更多详细信息:

在下面的代码中,ThisType实现了ThatType-ThatType是一个接口

//LinkedHashMap<Integer, ? extends ThatType> theMap = new LinkedHashMap<>();
LinkedHashMap<Integer, ThisType> theMap = new LinkedHashMap<>();
for (Integer key:intArray)  {
    ThisType a = new ThisType();
    if (theMap.containsKey(key))  {
        a = theMap.get(key);    
        a.doStuff();
    } else {
        a.doOtherStuff();
    }
    theMap.put(key, a);
}

最后,我想返回主题图作为ThatType**的集合,而不是**ThisType

这就是链条断开的地方。使用注释行(第一行)进行声明会在put()上出现类型不匹配错误get()散列的方法

不确定这是否重要,但是, 我将结果返回为LinkedHashSet<;那种类型>。我正在做从LinkedHashMapLinkedHashSet的转换。但是,对于映射或集合中集合值的多态引用,没有任何效果。到目前为止,我在所有这些操作中使用的所有且唯一的类型都是ThisType那种类型几乎在我尝试的任何地方都给了我一些错误


共 (3) 个答案

  1. # 1 楼答案

    在中声明通配符有界类型参数时

    LinkedHashMap<Integer, ? extends ThatType> theMap = new LinkedHashMap<>();
    

    您告诉编译器类型参数可以是ThatType的子类型的任何类。想象一下这种情况

    LinkedHashMap<Integer, ? extends ThatType> theMap = getLinkedHashMap();
    

    其中getLinkedHashMap()定义为

    public LinkedHashMap<Integer, OtherType /* which implements ThatType */> getLinkedHashMap();
    

    上一个赋值将起作用,因为OtherTypeThatType的子类型。然而,你不能期望

    ThisType a = theMap.get(key);
    

    工作。由于通配符的存在,您所知道的是映射肯定包含ThatType实例(称为上限),但它们可以是OtherTypeThatType类型(或ThatType的其他子类型)。你最多也能做到

    ThisType a = (ThisType) theMap.get(key);
    

    强制转换返回值,但随后您将向ClassCastException开放自己

    类似地,除了null之外,您不能用任何东西调用put()

    theMap.put(someInt, null); // will compile
    theMap.put(someInt, new ThisType()); // will not compile
    theMap.put(someInt, new OtherType()); // will not compile
    

    编译器不允许您添加任何内容,因为它无法保证映射包含的内容,同样是因为通配符绑定。但是^{} can be used because

    The null reference can always undergo a widening reference conversion to any reference type.

    所以null是一个有效的参数,因为它是the lower bound of the wildcard


    您处于一种特殊的情况下,您的方法似乎在内部创建了LinkedHashMap,并且您知道将传递给它什么。因此,您可以执行以下操作

    public static LinkedHashMap<Integer, ThatType> getTheSet(int[] intArray) {
        LinkedHashMap<Integer, ThatType> theMap = new LinkedHashMap<>();
    
        for (Integer key : intArray) {
            ThisType a = new ThisType();
            if (theMap.containsKey(key)) {
                a = (ThisType) theMap.get(key); // cast it because you know they will definitely be `ThisType` references
                a.doStuff();
            } else {
                a.doOtherStuff();
            }
            theMap.put(key, a);
        }
    
        return theMap;
    }
    

    由于ThisTypeThatType的子类型,因此可以将ThisType的实例放入映射中。您需要注意如何使用此方法的返回值。编译器只知道返回值包含ThatType引用。它不知道它们实际上是ThisType

  2. # 2 楼答案

    我想你想要的是使用通配符

     LinkedHashSet<? extends ThatType> someFunction(LinkedHashSet<? extends ThatType> set) {
          return set;
     }
    

    正如其他地方所解释的,LinkedHashSet<ThisType>不是LinkedHashSet<ThatType>的子类,因为LinkedHashSet<ThisType>不能接受ThatType对象

    LinkedHashSet<? extends ThatType>中的通配符表示某个类的LinkedHastSet(不确定是什么)扩展了ThatType

    虽然你可能想考虑使用这个词:

     Set<? extends ThatType> someFunction(Set<? extends ThatType> set) {
          return set;
     }
    
  3. # 3 楼答案

    您需要通配符Set<? super ThisType>。看看下面的例子

    public static void main(String[] args) {
        Set<ThatType> set=new LinkedHashSet<>();
        Set<ThisType> set2=new LinkedHashSet<>();
    
        someFunction(set);
        someFunction(set2);
    }
    
    static void someFunction(Set<? super ThisType> set) {
    
    }
    
    class ThisType implements ThatType{
    
    }
    interface ThatType{
    
    }