Ответ 1
Если у вас есть List<List<Integer>>
, тогда вы сможете добавить к нему LinkedList<Integer>
. Но вы не можете сделать это для ArrayList<ArrayList<Integer>>
, поэтому последний не может быть типом List<List<Integer>>
.
Следующая строка дает мне ошибку:
Incompatible Types.
List<List<Integer>> output = new ArrayList<ArrayList<Integer>>();
В чем причина?
ИЗМЕНИТЬ
Я понимаю, что если изменить свой второй список ArrayList на List, это не даст мне ошибку. Однако я хочу знать причину ошибки. Благодаря
Если у вас есть List<List<Integer>>
, тогда вы сможете добавить к нему LinkedList<Integer>
. Но вы не можете сделать это для ArrayList<ArrayList<Integer>>
, поэтому последний не может быть типом List<List<Integer>>
.
Это распространенное недоразумение, когда дело доходит до программирования с помощью дженерики, но это важная концепция для изучения.
Box<Integer>
не является подтипом Box, хотя Integer является подтипом Number.
Правильное письмо должно быть:
List<List<Integer>> ret = new ArrayList<List<Integer>>();
Так как вы можете добавить не только ArrayList
, но и LinkedList
в ret
Причина в том, что generics не ковариант.
Рассмотрим более простой случай:
List<Integer> integers = new ArrayList<Integer>();
List<Number> numbers = integers; // cannot do this
numbers.add(new Float(1337.44));
Теперь List содержит Float, что, безусловно, плохо.
То же самое для вашего случая.
List<ArrayList<Integer>> al = new ArrayList<ArrayList<Integer>>();
List<List<Integer>> ll = al; // cannot do this
ll.add(new LinkedList<Integer>())
Теперь у вас есть список ll
, который содержит LinkedList
, но al
объявлен как Список ArrayList
s.
Это четко указано в Java Doc
В общем случае, если Foo является подтипом (подклассом или подинтерфейсом) Bar и G - это объявление общего типа, это не тот случай, когда
G<Foo>
подтипG<Bar>
. Это, наверное, самое сложное, что вам нужно узнайте о дженериках, потому что это противоречит нашей глубоко укоренившейся интуитивные.
То же самое происходит здесь Bar = List<Integer>
и Foo = ArrayList<Integer>
, поскольку ArrayList<ArrayList<Integer>>
не является подтипом List<List<Integer>>