可以说我们有一个包含此类的程序:
public interface AbstractItem {
}
public SharpItem implements AbstractItem {
}
public BluntItem implements AbstractItem {
}
public interface AbstractToolbox {
//well the problem starts here...
public List<AbstractItem> getItems();
}
public ExpensiveToolbox implements AbstractToolbox {
private List<SharpItem> items = new ArrayList()<SharpItems>;
public List<SharpItem> getItems() { return this.items; }
}
public CheapTooblox implements AbstractToolbox {
private List<BluntItem> items = new ArrayList()<BluntItem>;
public List<BluntItem> getItems() { return this.items; }
}
容易吧?好吧,可以说我们现在想要制作这样的方法(在某个随机类中):
public void doImportantStuff(AbstractToolbox toolbox) {
//important stuff!
//this obviously won't work
List<AbstractToolbox> items = toolbox.getItems();
//do some stuffwith all items
}
现在的问题是,在Java的泛型集合不是协变的(希望这是我要找的术语),我不能分配ArrayList<ExpensiveToolbox>
给一个List<AbstractToolbox>
。我在这里看到的唯一解决方案是复制代码并为每种类型做一个版本,但这显然很糟糕(如果我们有更多的类用不同的列表实现AbstractToolbox会怎样?)。哦,显然,第二种解决方法是删除泛型并创建一个普通的List,但这是一个好习惯吗?
是否有解决此类问题的设计模式/实践?
@Edit:好的,所以我可能不够精确。我希望所有扩展AbstractToolbox的类都具有某些扩展AbstractItem的类的列表,然后我想要一个方法,该方法将AbstractToolbox作为参数并对其列表中的项目进行某些操作(使用将在AbstractItem,因此每个可能的列表中的所有项目实际上都具有它们)。
您可能需要看一下对通配符使用通配符类型。快速链接如下:
什么是PECS(生产者扩展了超级消费者)?
快速解答:将类型更改为 List<? extends AbstractItem>
你为什么不能分配这个?
想象一下这里的代码…
List<AbstractItem> foo = new ArrayList<SharpItem>();
foo.add(new BluntItem());
静态打字说这应该工作…但是你不能这样做!它将违反ArrayList的类型。这就是为什么不允许这样做。如果您将其更改为
List<? extends AbstractItem> foo = new ArrayList<SharpItem>();
然后,您可以进行分配,但不要在列表中添加任何内容。但是,您仍然可以从列表中检索元素作为AbstractItems。
仅使用列表(裸类型)是否是一个好的解决方案?
不,绝对不是:-p
问题内容: 请显示一个有关Java中协方差和逆方差的好例子。 问题答案: 协方差: Sub#getSomething是协变的,因为它返回Super#getSomething的返回类型的子类(但完全填充了Super.getSomething()的协定) 逆差 Sub#doSomething是互变的,因为它采用了Super#doSomething的参数的超类的参数(但是,再次填充了Super#doSo
sdiff key1 key2...keyN 返回所有给定key的差集 sdiffstore dstkey key1...keyN 同sdiff,并同时保存差集到dstkey下
问题内容: 谁能解释我,编程语言理论中协变和逆变的概念吗? 问题答案: 协方差 非常简单,最好从某些收集类的角度来考虑。我们可以 参数化 的一些类型参数类。也就是说,我们的列表包含some 类型的元素。如果,列表将是协变的 S是Tiff列表的子类型List [S]是List [T]的子类型 (在这里,我使用数学定义 iff 表示 当且仅当 。) 也就是说,a 是一个 。如果有一些例程接受a 作为参
你能解释一下第一行最后一个false输出,为什么它不是真的吗?
我正在学习Scala中的函数式编程原理,在学习子类型和泛型时,我对协方差有一个困惑: 给定:或是的子类型 编辑: 下面是的定义:
2.8.1. 基本收敛 尽管是协方差矩阵的无偏估计, 最大似然估计不是协方差矩阵的特征值的一个很好的估计, 所以从反演得到的精度矩阵是不准确的。 有时,甚至出现数学原因,经验协方差矩阵不能反转。 为了避免这样的反演问题,引入了经验协方差矩阵的一种变换方式:shrinkage 。 在 scikit-learn 中,该变换(具有用户定义的收缩系数) 可以直接应用于使用 shrunk_covarianc