Niepotrzebny iterator

0

Czemu twórcy wymyślili Iterator, jeżeli możemy zrobić to samo za pomocą fori ?

        List<String> stringList = new ArrayList<>();
        stringList.add("Name1");
        stringList.add("Name2");
        stringList.add("Name3");

        Iterator<String> iterator = stringList.iterator();
        while (iterator.hasNext()){
            String element = iterator.next();
            System.out.println(element + "\n");
        }

        for (int i = 0; i < stringList.size(); i++) {
            System.out.println(stringList.get(i) + "\n");
        }
2

Są takie kontenery, gdzie dostęp do itego get(i) elementu jest powolny. Za każdym razem trzeba iść od początku listy - see LinkedList.
Wtedy iterator to taki pomocniczy obiekt, który przechowuje dodatkowo ostatnio odwiedzony węzeł tej listy i przez to przechodzenie do następnego elementu jest dużo szybsze.
W przypadku ArrayList tego sensu nie widać.
Dodatkowo iterator to taki ogólny interfejs łażenia po strukturze. Czyli jak mamy jakieś algorytmy na listach itp. to piszemy je z wykorzystaniem iteratora i wtedy będzie też można wykorzystać implementację algorymtu np. dla zbioru - Set, czy nawet jakiegoś drzewa , jesli zaimplementujemy tam iterator.

1

Pomijając LinkedList to wiesz że na przykład Set nie ma uporządkowanej kolejności (tzn zwykły HashSet)?
Widac tu https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html metodę get?

1

To jest starożytna metoda przechodzenia po liście:

        for (int i = 0; i < stringList.size(); i++) {
            System.out.println(stringList.get(i) + "\n");
        }

Od Javy 5 dostępny jest taki zapis:

        for (String name : stringList) {
            System.out.println(name + "\n");
        }

Drugi zapis wymaga by typem stringList (czyli kolekcji po której iterujemy) była albo tablica albo coś co implementuje Iterable. Iterable ma metodę, która zwraca Iterator i to właśnie Iterator jest docelowo używany, tzn ten powyższy foreach jest na etapie kompilacji zamieniany dokładnie na to, co sam zaprezentowałeś, czyli:

        Iterator<String> iterator = stringList.iterator();
        while (iterator.hasNext()){
            String element = iterator.next();
            System.out.println(element + "\n");
        }

Jeśli stworzysz sobie własną klaskę, która implementuje Iterable to będziesz mógł jej użyć w Javowym foreachu. Polecam spróbować.

Uprzedzając ewentualne pytania: czemu foreach wymaga Iterable, a nie Iterator? Gdyż Iterator zmienia stan podczas iterowania i nie można go użyć dwukrotnie (nie ma metody reset ani niczego podobnego). Iterable ma metodę iterator(), która zwraca świeżego Iteratora za każdym razem, więc można iterować wielokrotnie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1