Java

[Java]반복자(Iterator)

DevStory 2022. 5. 2.

반복자(Iterator)란?

Java의 Iterator 인터페이스는 Collection Framework의 구성요소로 컬렉션을 순회하여 요소를 접근하는 경우 사용됩니다.


Iterator 인터페이스 특징

  1. Iterator 인터페이스는 Java 1.2 컬렉션 프레임워크부터 사용할 수 있습니다.
  2. 컬렉션 객체를 순회하여 요소를 접근합니다.
  3. 모든 컬렉션에서 사용할 수 있으므로 "Universal Java Cursor"로 알려져 있습니다.
  4. Iterator 인터페이스는 읽기(Read)쓰기(Write) 작업을 지원합니다. 즉, 컬렉션 객체를 순회하여 요소를 제거할 수 있습니다.

Iterator 인터페이스의 메서드

다음은 Iterator 인터페이스의 세 가지 핵심 메서드입니다.


next() 메서드

next() 메서드는 컬렉션의 다음 요소를 반환합니다. 더 이상 요소가 없으면 NosuchElementException이 발생합니다.


hasNext() 메서드

hasNext() 메서드는 컬렉션 객체를 순회하여 다음 요소가 존재하는지 확인합니다. 다음 요소가 존재하는 경우 True가 반환되고 그렇지 않으면 False가 반환됩니다. 즉, hasNext() 메서드를 사용하여 next() 메서드를 호출할지 결정할 수 있습니다.


remove() 메서드

remove()는 현재 요소를 제거합니다. Iterator가 제거 작업을 지원하지 않으면 UnsupportedOperation을 발생시킵니다. 그리고 next() 메서드가 호출되지 않았는데 remove() 메서드를 호출하면 IllegalStateException이 발생합니다.


Iterator 예제

다음 예제는 Iterator를 사용하여 ArrayList를 순회합니다.

ArrayList aList = new ArrayList<String>();
aList.add("One");
aList.add("Two");
aList.add("Three");

// iterator() 메서드를 호출하여 Iterator 객체를 가져옵니다. 
Iterator iterator = aList.iterator();
 
// hasNext() 메서드를 사용하여 컬렉션 객체를 순회합니다.
while( iterator.hasNext() ){
  // next() 메서드를 사용하여 컬렉션 객체의 현재 요소를 가져옵니다.
  System.out.println( iterator.next() );
}

실행 결과

One
Two
Three

next() 메서드는 접근할 수 있는 요소가 없는 경우 NoSuchElementException을 전달합니다. 그러므로 다음 요소가 있는지 확인하기 위해 next() 메서드가 아닌 hasNext() 메서드를 사용하도록 합니다.


Iterator의 단점 및 한계

  1. 다음 요소가 아닌 특정 요소를 접근하거나 새로운 요소를 추가하는 작업은 불가능합니다.
  2. 요소를 접근하는 방향은 순방향으로만 진행됩니다. 즉, 역방향으로 컬렉션 객체의 요소를 접근할 수 없습니다.
  3. 컬렉션 객체의 요소는 순차적으로 접근합니다.

ListIterator 인터페이스

ListIterator 인터페이스는 Iterator의 하위 인터페이스입니다. ArrayList, LinkedList 등 List로 구성된 컬렉션에서 작동합니다.


ListIterator 인터페이스 특징

  1. ListIterator 인터페이스는 추가, 읽기, 수정 및 삭제와 같은 CRUD 작업을 지원합니다.
  2. ListIterator 인터페이스는 Iterator 인터페이스의 단점을 극복하기 위해 기능이 확장되었습니다.
  3. 컬렉션 객체의 요소를 역방향으로 접근할 수 있습니다.
  4. 주로 List로 구성된 컬렉션(ArrayList, LinkedList)에서 작동합니다.
  5. Java 1.2부터 사용 가능합니다.

ListIterator 인터페이스의 메서드

ListIterator 인터페이스의 메서드 next(), hasNext() 및 remove() 메서드는 Iterator 메서드와 동일한 방식으로 동작합니다. 다음은 ListIterator 인터페이스에서 기능이 확장된 메서드입니다.


previous() 메서드

previous() 메서드는 컬렉션의 이전 요소를 반환합니다. 이전 요소가 반환되면 커서는 역방향으로 이동합니다.


hasPrevious() 메서드

hasPrevious() 메서드는 역방향으로 요소가 존재하는지 확인합니다. 요소가 존재하는 경우 True가 반환되고 그렇지 않으면 False가 반환됩니다.


previousIndex() 메서드

previousIndex() 메서드는 이전 요소의 인덱스를 반환합니다.


nextIndex() 메서드

nextIndex() 메서드는 다음 요소의 인덱스를 반환합니다.


set() 메서드

마지막 요소를 주어진 요소로 변경합니다.


add() 메서드

새로운 요소를 다음 추가합니다.


ListIterator 예제

다음은 ListIterator를 사용하여 ArrayList를 순방향 및 역방향으로 순회합니다.

ArrayList aList = new ArrayList<String>();
aList.add("One");
aList.add("Two");
aList.add("Three");

ListIterator iterator = aList.listIterator();
 
System.out.println("순방향");
while( iterator.hasNext()) {
  System.out.print( iterator.next() + " ");
}
 
System.out.println("\n역방향");
while( iterator.hasPrevious()) {
  System.out.print( iterator.previous() + " " );
}

실행 결과

순방향
One Two Three
역방향
Three Two One
반응형

remove() 메서드 사용

다음 예제는 Iterator의 remove() 메서드를 사용하는 예제입니다.

ArrayList<String> aList = new ArrayList<String>();
aList.add("A");
aList.add("B");
aList.add("C");
 
Iterator<String> iterator = aList.iterator();
 
String str = null;

while(iterator.hasNext()){
  str = iterator.next();
  if(str.equalsIgnoreCase("A")){
    iterator.remove();
  }
}

System.out.println(aList);

실행 결과

[B, C]

remove() 메서드는 next() 메서드 호출 전에 사용되거나 동일한 요소에 두 번 이상 호출하면 IllegalStateException을 전달합니다.

 

그리고 remove() 메서드를 지원하지 않는 컬렉션에서 remove() 메서드를 호출하면 UnsupportedOperationException을 전달합니다. 예를 들어 Arrays 클래스의 asList() 메서드를 사용하여 생성된 컬렉션 객체는 remove() 메서드를 지원하지 않습니다.

String[] strColors = {"A", "B", "C"};
List<String> list = Arrays.asList(strColors);

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

String str = null;

while(iterator.hasNext()){
  str = iterator.next();
  if(str.equalsIgnoreCase("A")){
    iterator.remove();
  }
}

System.out.println(list);

예제

다음은 컬렉션의 객체들을 Iterator을 사용하여 순회하는 예제 코드입니다.


TreeSet

TreeSet<String> tSet = new TreeSet<String>();
 
tSet.add("A");
tSet.add("C");
tSet.add("B");
tSet.add("D");
 
Iterator<String> iterator = tSet.iterator();

while( iterator.hasNext() ) {
  System.out.print( iterator.next() + " ");
}

실행 결과

A B C D

HashSet

HashSet<String> hSet = new HashSet<String>();

hSet.add("A");
hSet.add("C");
hSet.add("B");
hSet.add("D");

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

while( iterator.hasNext() ) {
  System.out.print( iterator.next() + " ");
}

실행 결과

A B C D

ArrayList

ArrayList<String> aList = new ArrayList<String>();

aList.add("A");
aList.add("C");
aList.add("B");
aList.add("D");

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

while( iterator.hasNext() ) {
  System.out.print( iterator.next() + " ");
}

실행 결과

A C B D

LinkedList

LinkedList<String> lList = new LinkedList<String>();

lList.add("A");
lList.add("C");
lList.add("B");
lList.add("D");

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

while( iterator.hasNext() ) {
  System.out.print( iterator.next() + " ");
}

실행 결과

A C B D

HashMap

Key를 순회

HashMap<String, Integer> hMap = new HashMap<String, Integer>();

hMap.put("Key1", 1);
hMap.put("Key3", 3);
hMap.put("Key2", 2);
hMap.put("Key4", 4);

Set<String> keys = hMap.keySet();

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

while( iterator.hasNext() ) {
  System.out.print( iterator.next() + " ");
}

실행 결과

Key2 Key1 Key4 Key3

 

Value를 순회

HashMap<String, Integer> hMap = new HashMap<String, Integer>();

hMap.put("Key1", 1);
hMap.put("Key3", 3);
hMap.put("Key2", 2);
hMap.put("Key4", 4);

Collection values = hMap.values();

Iterator<Integer> iterator = values.iterator();

while( iterator.hasNext() ) {
  System.out.print( iterator.next() + " ");
}

실행 결과

2 1 4 3

 

Key-Value 쌍을 순회

HashMap<String, Integer> hMap = new HashMap<String, Integer>();

hMap.put("Key1", 1);
hMap.put("Key3", 3);
hMap.put("Key2", 2);
hMap.put("Key4", 4);

Set<Map.Entry<String, Integer>> entrySet = hMap.entrySet();

Iterator<Map.Entry<String, Integer>> iterator = entrySet.iterator();

while( iterator.hasNext() ) {
  Map.Entry<String, Integer> entry = iterator.next();
  System.out.println( "Key: " + entry.getKey() + " / Value: " + entry.getValue() );
}

실행 결과

Key: Key2 / Value: 2
Key: Key1 / Value: 1
Key: Key4 / Value: 4
Key: Key3 / Value: 3

TreeMap

Key를 순회

TreeMap<String, Integer> tMap = new TreeMap<String, Integer>();

tMap.put("Key1", 1);
tMap.put("Key3", 3);
tMap.put("Key2", 2);
tMap.put("Key4", 4);

Set<String> keys = tMap.keySet();

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

while( iterator.hasNext() ) {
  System.out.print( iterator.next() + " " );
}

실행 결과

Key1 Key2 Key3 Key4

 

Value를 순회

TreeMap<String, Integer> tMap = new TreeMap<String, Integer>();

tMap.put("Key1", 1);
tMap.put("Key3", 3);
tMap.put("Key2", 2);
tMap.put("Key4", 4);

Collection<Integer> values = tMap.values();

Iterator<Integer> iterator = values.iterator();

while( iterator.hasNext() ) {
  System.out.print( iterator.next() + " ");
}

실행 결과

1 2 3 4

 

Key-Value 쌍을 순회

TreeMap<String, Integer> tMap = new TreeMap<String, Integer>();

tMap.put("Key1", 1);
tMap.put("Key3", 3);
tMap.put("Key2", 2);
tMap.put("Key4", 4);

Set<Map.Entry<String, Integer>> entrySet = tMap.entrySet();

Iterator<Map.Entry<String, Integer>> iterator = entrySet.iterator();

while( iterator.hasNext() ) {
  Map.Entry<String, Integer> entry = iterator.next();
  System.out.println( "Key: " + entry.getKey() + " / Value: " + entry.getValue() );
}

실행 결과

Key: Key1 / Value: 1
Key: Key2 / Value: 2
Key: Key3 / Value: 3
Key: Key4 / Value: 4

LinkedMap

Key를 순회

LinkedHashMap<String, Integer> lhMap = new LinkedHashMap<String, Integer>();

lhMap.put("Key1", 1);
lhMap.put("Key3", 3);
lhMap.put("Key2", 2);
lhMap.put("Key4", 4);

Set<String> keys = lhMap.keySet();

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

while( iterator.hasNext() ) {
  System.out.print( iterator.next() + " ");
}

실행 결과

Key1 Key3 Key2 Key4

 

Value를 순회

LinkedHashMap<String, Integer> lhMap = new LinkedHashMap<String, Integer>();

lhMap.put("Key1", 1);
lhMap.put("Key3", 3);
lhMap.put("Key2", 2);
lhMap.put("Key4", 4);

Collection<Integer> values = lhMap.values();

Iterator<Integer> iterator = values.iterator();

while( iterator.hasNext() ) {
  System.out.print( iterator.next() + " ");
}

실행 결과

1 3 2 4

 

Key-Value 쌍을 순회

LinkedHashMap<String, Integer> lhMap = new LinkedHashMap<String, Integer>();

lhMap.put("Key1", 1);
lhMap.put("Key3", 3);
lhMap.put("Key2", 2);
lhMap.put("Key4", 4);

Set<Map.Entry<String, Integer>> entrySet = lhMap.entrySet();

Iterator<Map.Entry<String, Integer>> iterator = entrySet.iterator();

while( iterator.hasNext() ) {
  Map.Entry<String, Integer> entry = iterator.next();
  System.out.println( "Key: " + entry.getKey() + " / Value: " + entry.getValue() );
}

실행 결과

Key: Key1 / Value: 1
Key: Key3 / Value: 3
Key: Key2 / Value: 2
Key: Key4 / Value: 4
반응형

댓글