web-dev-qa-db-fra.com

Types incompatibles List of List et ArrayList of ArrayList

La ligne ci-dessous me donne une erreur:

Incompatible Types.

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

Quelle est la raison?

MODIFIER

Je comprends que si je change ma deuxième liste de tableaux en liste, cela ne me donne pas d'erreur. Je veux cependant connaître la raison de l'erreur. Merci

21
Kraken

Si vous aviez un List<List<Integer>> vous pourrez alors ajouter un LinkedList<Integer> à elle. Mais vous ne pouvez pas faire cela pour un ArrayList<ArrayList<Integer>>, ce dernier ne peut donc pas être un type de List<List<Integer>>.

16
Dawood ibn Kareem

De génériques, héritage et sous-types

Il s'agit d'un malentendu courant en matière de programmation avec des génériques, mais c'est un concept important à apprendre.

enter image description here

Box<Integer> n'est pas un sous-type de Box même si Integer est un sous-type de Number.

24
Ankit Lamba

L'écriture correcte devrait être: List<List<Integer>> ret = new ArrayList<List<Integer>>(); Puisque de cette façon, vous pouvez ajouter non seulement ArrayList mais aussi LinkedList à ret

16
Bin Feng

La raison en est que les génériques ne sont pas covariant .

Prenons un cas plus simple:

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

Maintenant, List détient un flotteur, ce qui est certainement mauvais.

Même chose pour votre cas.

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

Vous avez maintenant une liste ll qui contient LinkedList, mais le al est déclaré comme une liste de ArrayLists.

8
lpiepiora

Il est clairement indiqué dans Java Doc

En général, si Foo est un sous-type (sous-classe ou sous-interface) de Bar, et G est une déclaration de type générique, ce n'est pas le cas que G<Foo> est un sous-type de G<Bar>. C'est probablement la chose la plus difficile à apprendre sur les génériques, car cela va à l'encontre de nos intuitions profondes.

La même chose se produit ici c'est Bar = List<Integer> et Foo = ArrayList<Integer> comme ArrayList<ArrayList<Integer>> n'est pas un sous-type de List<List<Integer>>

5
CoderCroc

Moins de texte plus de corrections:

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

ou

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