web-dev-qa-db-ja.com

互換性のないタイプList of ListおよびArrayList of ArrayList

以下の行は私にエラーを与えます:

Incompatible Types.

List<List<Integer>> output = new ArrayList<ArrayList<Integer>>();

理由は何ですか?

[〜#〜] edit [〜#〜]

2番目のArrayListをListに変更しても、エラーにはなりません。しかし、エラーの理由を知りたいです。ありがとう

21
Kraken

List<List<Integer>>がある場合は、LinkedList<Integer>を追加できます。ただし、ArrayList<ArrayList<Integer>>に対してこれを行うことはできないため、後者をList<List<Integer>>のタイプにすることはできません。

16

From Generics、Inheritance、およびSubtypes

これは、ジェネリックを使用したプログラミングに関してよくある誤解ですが、学ぶべき重要な概念です。

enter image description here

Box<Integer>は、IntegerがNumberのサブタイプであっても、Boxのサブタイプではありません。

24
Ankit Lamba

List<List<Integer>> ret = new ArrayList<List<Integer>>();このようにして、ArrayListだけでなくLinkedListretに追加できます。

16
Bin Feng

その理由は、ジェネリックは 共変ではないからです

より単純なケースを検討してください。

List<Integer> integers = new ArrayList<Integer>();
List<Number> numbers = integers; // cannot do this
numbers.add(new Float(1337.44));

リストはフロートを保持していますが、これは確かに悪いです。

あなたの場合も同じです。

List<ArrayList<Integer>> al = new ArrayList<ArrayList<Integer>>();
List<List<Integer>> ll = al; // cannot do this
ll.add(new LinkedList<Integer>())

llを保持するリストLinkedListができましたが、alArrayListsのリストとして宣言されています。

8
lpiepiora

Java Doc に明記されています

一般に、FooがBarのサブタイプ(サブクラスまたはサブインターフェース)であり、Gが一般的な型宣言である場合、_G<Foo>_が_G<Bar>_。これはおそらく、ジェネリックについて深く学ぶべき直観に反するため、ジェネリックについて学ぶ必要がある最も難しいことです。

ここでも同じことが起こります。_Bar = List<Integer>_と_Foo = ArrayList<Integer>_は_ArrayList<ArrayList<Integer>>_が_List<List<Integer>>_のサブタイプではないためです

5
CoderCroc

テキストの削減とその他の修正:

List<List<Integer>> lists = new ArrayList<>();

または

List<List<Integer>> lists = new ArrayList<List<Integer>>();
0
Pavel Shkleinik