Почему итератору нужен приведение для общих списков - PullRequest
1 голос
/ 31 декабря 2011
class ZiggyTest{

    public static void main(String[] args){

        List<Integer> list = new LinkedList<Integer>();
        list.add(4);
        list.add(5);
        list.add(-5);

        for(Iterator i = list.iterator(); i.hasNext();){
            Integer in = i.next();
            System.out.println(in);
        }
    }

}

Приведенный выше пример кода приводит к следующей ошибке компилятора:

ZiggyTest.java:17: incompatible types
found   : java.lang.Object
required: java.lang.Integer
            Integer in = i.next();
                               ^
1 error

Почему метод Iterator.next () нуждается в приведении, когда Список, связанный с Итератором, объявлен в общем?

Ответы [ 2 ]

16 голосов
/ 31 декабря 2011

Результат Iterator.next() нуждается в приведении именно потому, что Iterator был неправильно объявлен без универсального типа шаблона.

Если у вас есть List<Integer>, тогда правильный тип дляитератор Iterator<Integer>:

for (Iterator<Integer> i = list.iterator(); i.hasNext(); ) {
    Integer in = i.next();
    System.out.println(in);
}

В качестве альтернативы напишите:

for (Integer in: list) {
    System.out.println(in);
}

и вообще избегайте явного итератора.

3 голосов
/ 31 декабря 2011

Если вы хотите избежать приведения, вам нужна обобщенная версия Iterator, которая в вашем случае равна Iterator<Integer>. Если вы посмотрите на javadoc метода List#iterator, вы увидите, что он возвращает обобщенную версию.

Так что просто измените цикл for на

for(Iterator<Integer> i = list.iterator(); i.hasNext();)

и все прекрасно скомпилируется.

Пример Oracle иллюстрирует ту же проблему, с которой вы только что столкнулись. В ex1 ошибка компиляции вызвана отсутствием приведения, а в ex2 это решается с помощью обобщенной версии итератора

...