Sobes.tech
Junior

Jakie są sposoby iteracji po kolekcjach w Java?

sobes.tech AI

Odpowiedź od AI

W Javie istnieje kilka sposobów iteracji po kolekcjach:

  • Pętla for z indeksem (dla kolekcji obsługujących dostęp po indeksie, np. ArrayList, LinkedList):
    Odpowiednia dla kolekcji, w których dostęp do elementów po indeksie jest wydajny.

    // Przykład iteracji po ArrayList
    ArrayList<String> list = new ArrayList<>();
    list.add("A");
    list.add("B");
    list.add("C");
    
    for (int i = 0; i < list.size(); i++) {
        String element = list.get(i);
        System.out.println(element);
    }
    
  • Rozszerzona pętla for (Enhanced for loop / for-each):
    Najczęściej używana i najwygodniejsza metoda w większości przypadków. Odpowiednia dla dowolnych kolekcji implementujących Iterable.

    // Przykład iteracji po ArrayList z użyciem for-each
    ArrayList<String> list = new ArrayList<>();
    list.add("A");
    list.add("B");
    list.add("C");
    
    for (String element : list) {
        System.out.println(element);
    }
    
  • Użycie iteratora (Iterator):
    Bardziej elastyczny sposób, pozwalający na usuwanie elementów podczas iteracji. Odpowiedni dla wszystkich kolekcji.

    // Przykład iteracji z użyciem Iteratora
    ArrayList<String> list = new ArrayList<>();
    list.add("A");
    list.add("B");
    list.add("C");
    
    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {
        String element = iterator.next();
        System.out.println(element);
        // Można bezpiecznie usuwać elementy
        // if (element.equals("B")) {
        //     iterator.remove();
        // }
    }
    
  • Użycie ListIterator (dla list):
    Specjalny iterator dla kolekcji implementujących List. Pozwala na poruszanie się do przodu i do tyłu, a także dodawanie i modyfikowanie elementów.

    // Przykład iteracji z użyciem ListIterator
    ArrayList<String> list = new ArrayList<>();
    list.add("A");
    list.add("B");
    list.add("C");
    
    ListIterator<String> listIterator = list.listIterator();
    while (listIterator.hasNext()) {
        String element = listIterator.next();
        System.out.println(element);
    }
    // Przykład iteracji wstecz
    while (listIterator.hasPrevious()) {
        String element = listIterator.previous();
        System.out.println(element);
    }
    
  • Streams API (od Java 8):
    Podejście funkcyjne z użyciem wyrażeń lambda. Pozwala na wykonywanie operacji na elementach kolekcji (np. filtrowanie, transformacje) w sposób deklaratywny. Iteracja odbywa się "wewnętrznie" w strumieniu.

    // Przykład iteracji z użyciem Streams API
    ArrayList<String> list = new ArrayList<>();
    list.add("A");
    list.add("B");
    list.add("C");
    
    list.stream()
        .forEach(element -> System.out.println(element));
    
    // Przykład z filtrowaniem i transformacją
    // list.stream()
    //     .filter(element -> element.startsWith("A"))
    //     .map(String::toLowerCase)
    //     .forEach(System.out::println);
    

Wybór metody zależy od konkretnego zadania, typu kolekcji i wymagań dotyczących wydajności. Dla większości przypadków najwygodniejsza jest rozszerzona pętla for. Jeśli konieczne jest usuwanie elementów podczas iteracji, należy użyć Iterator. Dla list, które wymagają dwukierunkowego przejścia, odpowiedni jest ListIterator. API Streams oferuje potężne możliwości przetwarzania danych w sposób deklaratywny.