- [Java] 자바에서 Iterator를 사용하는 이유2025년 03월 01일 21시 40분 00초에 업로드 된 글입니다.작성자: DandyNow728x90반응형
1. 자바에서 Iterator를 사용하는 이유
1. 컬렉션 순회 표준화
- 자바의 다양한 컬렉션(
List,Set,Map등)은 내부 구조가 다르기 때문에, 각 컬렉션에 맞는 순회 방식이 필요하다. Iterator는 이러한 다양한 컬렉션을 일관된 방식으로 순회할 수 있도록 표준화된 인터페이스를 제공한다.- 즉, 컬렉션의 종류에 상관없이
hasNext()와next()메서드를 사용하여 요소에 접근할 수 있다.
✅ 예제 코드
Iterator를 사용하면List,Set등 다양한 컬렉션을 일관된 방식으로 순회할 수 있다.import java.util.*; public class IteratorExample1 { public static void main(String[] args) { List<String> list = Arrays.asList("Apple", "Banana", "Cherry"); Set<String> set = new HashSet<>(list); // List 순회 Iterator<String> listIterator = list.iterator(); while (listIterator.hasNext()) { System.out.println("List item: " + listIterator.next()); } // Set 순회 Iterator<String> setIterator = set.iterator(); while (setIterator.hasNext()) { System.out.println("Set item: " + setIterator.next()); } } }💡
List와Set의 내부 구조는 다르지만,Iterator를 사용하여 동일한 방식으로 요소를 순회할 수 있다.
2. 요소의 안전한 제거
- 일반적인
for루프나 향상된for-each루프를 사용하여 컬렉션을 순회하면서 요소를 제거하면ConcurrentModificationException이 발생할 수 있다. Iterator의remove()메서드를 사용하면 순회 중에도 안전하게 요소를 제거할 수 있다.
✅ 예제 코드
Iterator의remove()메서드를 사용하면ConcurrentModificationException없이 요소를 안전하게 제거할 수 있다.import java.util.*; public class IteratorExample2 { public static void main(String[] args) { List<String> list = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry")); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String fruit = iterator.next(); if ("Banana".equals(fruit)) { iterator.remove(); // 안전하게 요소 제거 } } System.out.println("Updated list: " + list); // [Apple, Cherry] } }💡
for-each루프에서list.remove()를 직접 호출하면ConcurrentModificationException이 발생할 수 있지만,Iterator의remove()를 사용하면 안전하게 삭제할 수 있다.
3. 다양한 순회 방식 지원
Iterator는 기본적으로 단방향 순회만 지원한다.ListIterator를 사용하면previous()메서드를 이용하여 양방향 순회가 가능하다.- 예를 들어,
ArrayList에서ListIterator를 사용하면 앞뒤로 이동하며 요소를 탐색할 수 있다.
✅ 예제 코드
ListIterator를 사용하면 양방향 순회가 가능하다.import java.util.*; public class IteratorExample3 { public static void main(String[] args) { List<String> list = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry")); ListIterator<String> listIterator = list.listIterator(); // 정방향 순회 while (listIterator.hasNext()) { System.out.println("Forward: " + listIterator.next()); } // 역방향 순회 while (listIterator.hasPrevious()) { System.out.println("Backward: " + listIterator.previous()); } } }💡
ListIterator는previous()를 지원하여 앞뒤로 이동이 가능하며,Iterator보다 더 다양한 기능을 제공한다.
4. 컬렉션의 내부 구조 은닉
Iterator를 사용하면 컬렉션의 내부 구현을 알 필요 없이 요소를 순회할 수 있다.- 이를 통해 컬렉션의 종류가 변경되더라도
Iterator를 사용하는 코드의 변경을 최소화할 수 있다. - 다만, 컬렉션의 종류에 따라 성능이나 지원하는 기능이 달라질 수 있으므로, 적절한 컬렉션을 선택하는 것이 중요하다.
✅ 예제 코드
Iterator를 사용하면 컬렉션의 구현 방식을 몰라도 동일한 방식으로 요소를 가져올 수 있다.import java.util.*; public class IteratorExample4 { public static void main(String[] args) { Collection<String> collection; if (new Random().nextBoolean()) { collection = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry")); // List 사용 } else { collection = new HashSet<>(Arrays.asList("Apple", "Banana", "Cherry")); // Set 사용 } // 컬렉션 타입이 List인지 Set인지 몰라도 동일한 방식으로 순회 가능 Iterator<String> iterator = collection.iterator(); while (iterator.hasNext()) { System.out.println("Item: " + iterator.next()); } } }💡
collection이ArrayList일 수도 있고,HashSet일 수도 있지만,Iterator를 사용하면 이를 신경 쓸 필요 없이 동일한 방식으로 요소를 가져올 수 있다.
📌 정리
이유 주요 기능 코드 예제 1. 컬렉션 순회 표준화 List와Set을 동일한 방식으로 순회List와Set을 같은Iterator방식으로 순회2. 요소의 안전한 제거 remove()를 사용해ConcurrentModificationException방지Iterator.remove()를 사용하여 안전하게 요소 삭제3. 다양한 순회 방식 지원 ListIterator로 양방향 순회 가능next()와previous()를 사용한 순회4. 컬렉션의 내부 구조 은닉 컬렉션이 List인지Set인지 몰라도 순회 가능Collection을 다형성을 이용해Iterator로 순회
2. Iterator를 적극적으로 사용하는 대표적인 라이브러리
1. Java Collections Framework (JCF)
1️⃣ 대표적인 예:
ArrayList,HashSet,TreeMap등자바의 기본 컬렉션 프레임워크(
java.util패키지)는 대부분Iterator를 지원하며,iterator()메서드를 통해 요소를 순회할 수 있다.2️⃣ 활용 이유: 컬렉션 내부 구조를 몰라도 일관된 방식으로 순회 가능
3️⃣ 사용 예 (Iterator를 이용한 컬렉션 순회)
List<String> list = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry")); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); }✅ 현재 권장되는 방식 (forEach 사용)
list.forEach(System.out::println);📌 하지만,
Iterator.remove()를 사용해야 하는 경우에는 여전히Iterator를 활용하는 것이 필요하다.
2. Apache Commons Collections
1️⃣ 대표적인 예:
org.apache.commons.collections4.IteratorUtilsApache Commons Collections는 컬렉션을 다룰 때 유용한 기능을 제공하는 라이브러리이다.
이 라이브러리의IteratorUtils클래스는 Iterator 변환, 필터링, 체이닝 등 다양한 기능을 제공한다.2️⃣ 활용 이유:
Iterator를 불변(immutable)으로 만들거나, 필터링된Iterator생성 가능3️⃣ 사용 예 (불변 Iterator 생성)
import org.apache.commons.collections4.IteratorUtils; import java.util.*; public class ApacheCommonsExample { public static void main(String[] args) { List<String> list = Arrays.asList("Apple", "Banana", "Cherry"); Iterator<String> iterator = IteratorUtils.unmodifiableIterator(list.iterator()); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }📌 현재 방식:
Stream을 이용해 불변 리스트를 만들 수 있음List<String> immutableList = List.of("Apple", "Banana", "Cherry"); immutableList.forEach(System.out::println);하지만
IteratorUtils를 사용하면 기존Iterator를 불변으로 만들 수 있다는 장점이 있음.
3. Guava (Google Collections Library)
1️⃣ 대표적인 예:
com.google.common.collect.IteratorsGoogle의 Guava 라이브러리는
Iterator를 보다 효율적으로 사용할 수 있도록 다양한 유틸리티를 제공한다.
예를 들어,Iterators.filter()를 사용하면 특정 조건을 만족하는 요소만 걸러낼 수 있다.2️⃣ 활용 이유:
Iterator기반 필터링, 변환, 결합 등의 편의 기능 제공3️⃣ 사용 예 (필터링된 Iterator 생성)
import com.google.common.collect.Iterators; import java.util.*; public class GuavaExample { public static void main(String[] args) { List<String> list = Arrays.asList("Apple", "Banana", "Cherry", "Avocado"); Iterator<String> iterator = Iterators.filter(list.iterator(), item -> item.startsWith("A")); while (iterator.hasNext()) { System.out.println(iterator.next()); // Apple, Avocado } } }✅ 현재 방식: Stream을 이용한 필터링
list.stream() .filter(s -> s.startsWith("A")) .forEach(System.out::println);하지만
Iterator를 기반으로 처리해야 하는 경우에는 여전히 Guava의Iterators가 유용함.
4. Hibernate (
org.hibernate.Query)1️⃣ 대표적인 예:
Query.iterate()Hibernate에서는 대량의 데이터를 조회할 때 한꺼번에 로드하는 것이 아니라, 한 행씩 순회하면서 처리할 수 있도록
Iterator를 제공한다.
이 방식은 메모리 절약 효과가 크다.2️⃣ 활용 이유: 대량의 데이터 처리 시 메모리 절약 효과
3️⃣ 사용 예 (Hibernate Query.iterate() 사용)
import org.hibernate.Session; import org.hibernate.query.Query; import java.util.Iterator; public class HibernateExample { public static void main(String[] args) { Session session = HibernateUtil.getSessionFactory().openSession(); Query<String> query = session.createQuery("SELECT name FROM Product", String.class); Iterator<String> iterator = query.iterate(); while (iterator.hasNext()) { System.out.println(iterator.next()); } session.close(); } }✅ 현재 방식:
Stream을 활용한 데이터베이스 조회 (Stream API + JPA)List<String> productNames = entityManager .createQuery("SELECT p.name FROM Product p", String.class) .getResultStream() .collect(Collectors.toList()); productNames.forEach(System.out::println);하지만 대용량 데이터 처리에서는 여전히
iterate()방식이 유용할 수 있음.
5. Jackson (
com.fasterxml.jackson.databind)1️⃣ 대표적인 예: JSON 데이터 스트리밍 (
JsonParser)Jackson 라이브러리는 JSON 데이터를 다룰 때
Iterator기반의 스트리밍 API를 제공한다.
이를 통해 JSON을 한꺼번에 로드하지 않고, 한 요소씩 순차적으로 처리할 수 있다.2️⃣ 활용 이유: JSON을 한 요소씩 읽어 메모리 사용량을 줄일 수 있음
3️⃣ 사용 예 (JsonParser를 활용한 JSON 순회)
import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import java.io.StringReader; public class JacksonExample { public static void main(String[] args) throws Exception { String json = "[\"Apple\", \"Banana\", \"Cherry\"]"; JsonFactory factory = new JsonFactory(); JsonParser parser = factory.createParser(new StringReader(json)); while (parser.nextToken() != JsonToken.END_ARRAY) { System.out.println(parser.getText()); } parser.close(); } }✅ 현재 방식: JSON을
List로 변환 후 처리ObjectMapper objectMapper = new ObjectMapper(); List<String> fruits = objectMapper.readValue(json, new TypeReference<List<String>>() {}); fruits.forEach(System.out::println);하지만 대용량 JSON을 처리할 때는 여전히
JsonParser기반의 Iterator 방식이 유리함.
📌 정리
라이브러리 주요 활용 대표적인 클래스/메서드 현재 권장 방식 Java Collections Framework 컬렉션 순회 및 요소 제거 iterator()forEach()Apache Commons Collections Iterator변환 및 조작IteratorUtils.unmodifiableIterator()List.of()활용Guava Iterator기반 필터링 및 변환Iterators.filter()Stream.filter()Hibernate 대용량 데이터 조회 Query.iterate()getResultStream()Jackson JSON 데이터 스트리밍 처리 JsonParserObjectMapper.readValue()자바 8 이후
Stream API가 등장하면서Iterator의 활용도가 줄었지만,
✅ 대량 데이터 처리, ✅ 메모리 최적화, ✅ 컬렉션 변환 및 조작 등의 경우에는 여전히Iterator기반의 접근이 유용함. 🚀728x90반응형'언어·프레임워크 > Java' 카테고리의 다른 글
[Java] 인터페이스 개념을 USB로 이해하기 (2) 2025.06.08 [Java] 정보 은닉과 캡슐화: 객체 지향 프로그래밍의 핵심 원칙 (3) 2025.06.08 [Java] 윈도우에서 여러개의 Java 버전 관리 하기 (0) 2024.07.26 [Java] 추상 클래스(Abstract Class)와 인터페이스(Interface) (0) 2024.02.02 [Java] VS Code에서 Java extensions 설치 및 Package 생성 (0) 2022.09.13 다음글이 없습니다.이전글이 없습니다.댓글 - 자바의 다양한 컬렉션(