Философия Java


Итераторы - часть 2


  • Удалять последний элемент, возвращенный итератором, с помощью remove( ).
  • Это все. Это простая реализация итератора, но достаточно мощная (и существуют более изощренный ListIterator для List). Чтобы посмотреть, как это работает, позвольте вновь использовать программу CatsAndDogs.java, введенную ранее в этой главе. В оригинальной версии метод get( ) был использован для выбора каждого элемента, но в следующей измененной версии используется итератор:

    //: c09:CatsAndDogs2.java

    // Простой контейнер с итератором.

    import java.util.*;

    public class CatsAndDogs2 { public static void main(String[] args) { ArrayList cats = new ArrayList(); for(int i = 0; i < 7; i++) cats.add(new Cat(i)); Iterator e = cats.iterator(); while(e.hasNext()) ((Cat)e.next()).print(); } } ///:~

    Вы можете видеть, что последние несколько строк используют Iterator, чтобы пройти по последовательности вместо цикла for. С помощью итератора вам нет необходимости заботится о числе элементов в контейнере. Об этом беспокоится за вас hasNext( ) и next( ).

    В качестве другого примера, рассмотрим создание метода печати общего назначения:

    //: c09:HamsterMaze.java

    // Использование итератора.

    import java.util.*;

    class Hamster { private int hamsterNumber; Hamster(int i) { hamsterNumber = i; } public String toString() { return "This is Hamster #" + hamsterNumber; } }

    class Printer { static void printAll(Iterator e) { while(e.hasNext()) System.out.println(e.next()); } }

    public class HamsterMaze { public static void main(String[] args) { ArrayList v = new ArrayList(); for(int i = 0; i < 3; i++) v.add(new Hamster(i)); Printer.printAll(v.iterator()); } } ///:~

    Пристальнее всмотритесь в метод printAll( ). Обратите внимание, что здесь нет информации о типе последовательности. Все что у вас есть - это Iterator, и это все, что вам нужно знать о последовательности: так как вы можете получить следующий объект и так как вы знаете, когда вы подойдете к концу. Эта идея, получение контейнера объектов и прохождение по нему для выполнения операции для каждого элемента - достаточно мощная и будет просматриваться повсюду в этой книге.

    Пример является более общим, так как он косвенным образом использует метод Object.toString( ). Метод println( ) перегружается для всех примитивных типов так же, как и для Object; в каждом случае автоматически производится String путем вызова соответствующего метода toString( ).

    Хотя в этом нет необходимости, но вы можете быть более точны при использовании приведения, которое имеет тот же эффект, что и вызов toString( ):

    System.out.println((String)e.next());

    Однако в общем случае вы захотите сделать что-то большее, нежели вызов методов Object, так что вы вновь будете применять приведение типов. Вы должны принимать во внимание, что вам интереснее получить Iterator для последовательности определенного типа и приводить результирующие объекты к этому типу (если вы ошиблись, получите исключение времени выполнения).




    Начало  Назад  Вперед