컬렉션 프레임워크에서 리스트(List)는 데이터를 효율적으로 저장하고 접근하는 데 많이 사용됩니다. 리스트를 탐색하고 수정하는 방법에는 forEach, Iterator, ListIterator 같은 다양한 메서드가 있습니다. 이 글에서는 각각의 방법을 코드 예시와 함께 설명하고, ListIterator의 심화 개념인 양방향 탐색과 요소 추가/삭제 기능에 대해 상세히 다룹니다.
1. forEach를 이용한 리스트 탐색
Java 8에서 추가된 forEach 메서드는 간결하고 가독성이 좋은 코드로 리스트를 탐색하는 데 유용합니다. 내부적으로 Consumer 인터페이스를 사용해, 각 요소를 처리할 수 있습니다. 단, forEach는 단방향 탐색만 가능하며, 리스트의 크기나 구조를 수정할 수 없습니다.
코드 예시
import java.util.Arrays;
import java.util.List;
public class ForEachExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> {
System.out.println("Name: " + name);
});
}
}
위 코드에서는 forEach 메서드를 사용해 리스트의 모든 요소를 출력합니다. 가독성이 좋고, 불필요한 인덱스를 사용할 필요가 없어 효율적입니다. 다만, 리스트 요소를 변경하는 작업은 불가능합니다.
2. Iterator를 이용한 리스트 탐색 및 수정
Iterator는 forEach보다 다양한 기능을 제공합니다. 특히, 탐색 중 요소를 삭제할 수 있는 유일한 방법입니다. Iterator는 hasNext()와 next() 메서드를 사용해 단방향으로 리스트를 탐색하며, remove() 메서드를 통해 탐색 중인 요소를 삭제할 수 있습니다.
코드 예시
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class IteratorExample {
public static void main(String[] args) {
List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie"));
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
if ("Bob".equals(name)) {
iterator.remove(); // "Bob" 요소 삭제
}
}
System.out.println(names); // 출력 결과: [Alice, Charlie]
}
}
위 코드에서는 Iterator를 사용해 리스트의 각 요소를 탐색하면서, 특정 조건을 만족하는 요소(이 경우, "Bob")를 삭제합니다. Iterator는 remove 메서드를 통해 ConcurrentModificationException 없이 안전하게 요소를 제거할 수 있는 장점이 있습니다.
3. ListIterator를 이용한 양방향 탐색 및 수정
ListIterator는 Iterator의 확장된 버전으로, 리스트를 양방향으로 탐색하고, 요소를 추가하거나 삭제할 수 있는 기능을 제공합니다. ListIterator는 hasPrevious()와 previous() 메서드를 사용해 역방향 탐색이 가능하며, add()와 remove()를 통해 리스트 요소를 수정할 수 있습니다.
코드 예시
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorExample {
public static void main(String[] args) {
List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie"));
ListIterator<String> listIterator = names.listIterator();
// 순방향 탐색 및 요소 수정
while (listIterator.hasNext()) {
String name = listIterator.next();
if ("Bob".equals(name)) {
listIterator.set("Bobby"); // "Bob"을 "Bobby"로 변경
}
}
// 역방향 탐색 및 요소 추가
while (listIterator.hasPrevious()) {
String name = listIterator.previous();
if ("Alice".equals(name)) {
listIterator.add("Alex"); // "Alice" 앞에 "Alex" 추가
}
}
System.out.println(names); // 출력 결과: [Alex, Alice, Bobby, Charlie]
}
}
위 예시에서는 ListIterator를 사용하여 먼저 순방향으로 리스트를 탐색하면서 "Bob"을 "Bobby"로 수정한 후, 역방향으로 탐색하여 "Alice" 앞에 "Alex"를 추가했습니다. ListIterator는 양방향 탐색과 요소 추가/수정이 모두 가능하다는 점에서 유용합니다.
심화 개념: ListIterator의 양방향 탐색과 요소 추가/삭제
ListIterator는 Iterator와 달리 양방향 탐색이 가능한 점이 큰 장점입니다. next()와 previous() 메서드를 번갈아 사용할 수 있어 탐색 위치를 자유롭게 이동할 수 있습니다. 또한, set() 메서드를 통해 현재 요소를 수정할 수 있고, add() 메서드를 통해 현재 위치에 요소를 추가할 수도 있습니다.
양방향 탐색과 요소 추가/삭제
ListIterator는 add()와 remove() 메서드를 통해, 반복문 중에도 요소를 추가하거나 삭제할 수 있습니다. 하지만 add() 메서드는 요소를 현재 위치에 삽입하며, remove() 메서드는 바로 직전에 반환된 요소만 삭제할 수 있습니다.
코드 예시
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorAdvancedExample {
public static void main(String[] args) {
List<String> items = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry"));
ListIterator<String> iterator = items.listIterator();
// 요소 추가 및 삭제 예시
while (iterator.hasNext()) {
String item = iterator.next();
if ("Banana".equals(item)) {
iterator.add("Blueberry"); // "Banana" 뒤에 "Blueberry" 추가
iterator.remove(); // "Banana" 삭제
}
}
System.out.println(items); // 출력 결과: [Apple, Blueberry, Cherry]
}
}
이 코드에서 ListIterator는 "Banana"를 탐색하면서, 해당 위치에 "Blueberry"를 추가하고 "Banana"를 삭제했습니다. 이러한 기능은 요소의 위치를 정확히 제어할 수 있도록 도와주며, ConcurrentModificationException 없이 안전하게 리스트를 수정할 수 있습니다.
마무리
- forEach: 간단하게 요소를 탐색할 때 유용하지만, 리스트 수정은 불가능.
- Iterator: 단방향 탐색이 가능하며, 탐색 중 안전하게 요소를 삭제할 수 있음.
- ListIterator: 양방향 탐색과 요소의 추가/삭제 및 수정이 가능하여 유연하게 리스트를 다룰 수 있음.
리스트를 다룰 때 위 탐색 방법들을 상황에 맞게 사용하면 코드의 효율성과 가독성을 모두 높일 수 있습니다. ListIterator는 특히 요소의 추가, 삭제, 수정이 동시에 필요할 때 강력한 도구가 됩니다.
'Java > Java이론' 카테고리의 다른 글
List 정렬과 Comparator/Comparable 인터페이스 활용 (0) | 2024.11.06 |
---|---|
List와 배열 간의 상호 변환 (0) | 2024.11.04 |
멀티스레드 환경에서의 리스트 동기화: Collections.synchronizedList()와 CopyOnWriteArrayList 비교 (0) | 2024.10.30 |
자바에서 불변 리스트(Immutable List) 만들기: 멀티스레드 환경에서의 활용과 중요성 (0) | 2024.10.29 |
Java Stream을 사용한 리스트 처리 예제 (0) | 2024.10.23 |