본문 바로가기

[Java] 그래서 Iterator 는 왜 쓰는거임? 걍 for 쓰지;?

@Salieri2026. 2. 4. 10:55

 

 

제목은 어그로, 이거 보여주려고 어그로 끌었다. 

 

 


 

 

핵심 이유 3가지

1. 컬렉션 종류와 상관없는 '통일된 표준' 제공 (Polymorphism)

  ArrayList는 get(i)로 인덱스 접근이 빠르지만, HashSet은 인덱스가 없고, LinkedList는 인덱스 접근이 느립니다. Iterator를 사용하면 컬렉션이 어떤 구현체(List, Set, Queue)이든 상관없이 hasNext()(다음 거 있어?)와 next()(다음 거 줘)만으로 똑같이 순회할 수 있습니다. 즉, 나중에 자료구조를 바꿔도 순회하는 코드는 수정할 필요가 없습니다. 

 

 

쉽게 이해하면,

 

Java 속 Iterator는 만능 도구 인 셈, 만능 도구인 샘이다. 그래도 머릿속에 넣어둬야하는 건

 

Iterator<String> it = list.iterator();
it.next();   // 가능
it.previous(); // ❌ 없음

//그럼에도 불구하고, 만약에 뒤로 가고싶다면 ListIterator 를 써야함

 

2. 순회 중 '안전한 삭제' (가장 큰 실질적 이유)

일반적인 for-each 문을 돌면서 리스트의 요소를 직접 삭제하면 에러(ConcurrentModificationException)가 발생합니다. 하지만 Iterator는 순회 중에 요소를 안전하게 지울 수 있는 remove() 메서드를 제공합니다.

3. 내부 구현의 은닉 (Encapsulation)

데이터가 배열에 저장되었는지, 링크로 연결되었는지, 트리 구조인지 사용자는 알 필요가 없습니다. Iterator는 "다음 데이터 가져오기"라는 기능만 노출하므로 사용자는 데이터 구조의 복잡성을 신경 쓸 필요가 없습니다.

 

 

쉽게 이해하기 : 

 

자료구조마다 데이터를 꺼내는 방법(메서드)이 완전히 다릅니다. 개발자는 자료구조를 바꿀 때마다 코드를 다 뜯어고쳐야 합니다.

  • ArrayList (배열): list.get(0), list.get(1)처럼 숫자(인덱스)로 꺼내야 함.
  • HashSet (집합): 순서가 뒤죽박죽이라 숫자(인덱스)로 꺼낼 수 없음. 꺼내려면 복잡한 별도 처리가 필요함.
  • LinkedList (연결): get(i)를 쓸 수는 있지만, 효율이 나빠서 노드(Node)를 타고 이동해야 함.

 

 

코드 비교: 왜 Iterator가 필요한가?

상황: 리스트를 돌면서 "B"라는 글자를 지우고 싶다.

❌ 안 좋은 예 (에러 발생)

for-each 문은 내부적으로 Iterator를 쓰지만, 순회 도중 원본 리스트(list.remove)를 건드리면 정합성이 깨져 에러가 납니다.

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));

// ConcurrentModificationException 발생!
for (String str : list) {
    if (str.equals("B")) {
        list.remove(str); // 반복문 도중에 리스트 크기가 변해서 에러 발생
        
    }
}

 

 

쉽게 말해 :

 

"지우는 거 까지는 되는데, 갑자기 ㅇ? 머야 이거 왜 지워짐? 내가 받은 건 여기에 3개 있어야 하는데 2개밖에 없는데?" 

 

"뿌애앵앵 나 안 할 거야 ~ 자꾸 데이터가 변해 이거 버그야 이거 오류야 이상한 거야 고쳐줘! " 

 

하면서 

 

ConcurrentModificationException를 던지는 것임

 

 

✅ 좋은 예 (Iterator 사용)

Iterator의 remove()는 현재 위치를 정확히 알고 있어 안전하게 삭제하고 다음 순서를 조정함

Iterator<String> iterator = list.iterator();

while (iterator.hasNext()) {
    String str = iterator.next();
    if (str.equals("B")) {
        iterator.remove(); // 에러 없이 안전하게 삭제됨
    }
}

 

 

 

요약

  1. 표준화: List, Set 등 어떤 자료구조든 똑같은 코드로 데이터를 꺼낼 수 있다.
  2. 안전한 삭제: 루프 도는 중에 데이터를 삭제해야 한다면 Iterator가 필수다.
  3. 참고: 우리가 편하게 쓰는 향상된 for (String s : list) 문법도 컴파일하면 내부적으로는 Iterator를 사용하는 코드로 변환됩니다. 다만 remove 기능이 없을 뿐입니다.

 

 


;

AI 로 개발하면 빠른데, 당신이 코드는 쓸줄 알아야할거아니야..
Salieri
@Salieri :: 살리에리의 인생살이 채널

평소에 내가 좋아하는것과 싫어하는 것들 그리고 왜 안되나 싶은 것들을 업로드 하는 블로그입니다 인생살이도 업로드 하고있어요. 제가 걸어온 길이 당신에게 있어서 도움이 되는 이정표였으면 좋겠네요. 질문은 항상 넓은 마음으로 받고있답니다. 대답하기 곤란한 질문이 아닌 이상 제에게 이메일을 써주세요 트위터 : https://twitter.com/@Salieri1845799 깃허브 : https://github.com/salieri009

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차