"안녕, 아미고!"

"안녕, 엘리!"

"오늘은 반복자에 대해 이야기하고 싶습니다."

"반복자는 사실상 컬렉션과 동시에 발명되었습니다. 컬렉션의 주요 목적은 요소를 저장하는 것이며 반복자의 주요 목적은 이러한 요소를 하나씩 검색하는 것입니다."

"요소 집합을 얻는 것이 무엇이 그렇게 어려운가요?"

"첫째, Set과 같은 일부 컬렉션의 요소에는 정해진 순서가 없거나 순서가 지속적으로 변경됩니다."

"두 번째로, 일부 데이터 구조는 매우 복잡한 방식으로 개체를 저장할 수 있습니다. 다른 그룹, 목록 등에 있습니다. 즉, 모든 요소를 ​​순서대로 전달하는 것은 사소한 작업이 아닙니다."

"셋째, 컬렉션은 변경되는 경향이 있습니다. 컬렉션의 전체 내용을 표시하기로 결정했지만 출력 중간에서 JVM이 컬렉션 요소의 절반을 대체하는 다른 스레드로 전환한다고 가정합니다. 따라서 출력 대신 누가 뭘 알아."

"흠..."

"하지만! 이것들은 바로 이터레이터가 해결할 수 있는 종류의 문제입니다. 이터레이터는 한편으로는 모든 프라이빗 데이터에 액세스할 수 있고 내부 구조를 알고 있는 컬렉션 내의 특수 객체입니다. , 공개 Iterator 인터페이스를 구현하여 모든 사람이 작업 방법을 알 수 있습니다. "

"일부 이터레이터에는 이터레이터가 생성될 때 컬렉션의 모든 요소가 복사되는 내부 배열이 있습니다. 이렇게 하면 컬렉션에 대한 후속 변경 사항이 요소의 수나 순서에 영향을 미치지 않습니다."

" for each 로 작업할 때 이 문제를 접한 것 같습니다 . 컬렉션을 반복하면서 동시에 컬렉션에서 요소를 제거할 수 없습니다. 이것은 모두 반복자가 작동하는 방식 때문입니다."

"동시성 라이브러리에 추가된 새 컬렉션에서 반복자는 이 문제를 제거하기 위해 재작업되었습니다."

"반복자가 어떻게 작동하는지 알려드리겠습니다."

"Java에는 특별한 Iterator 인터페이스가 있습니다. 다음은 그 방법입니다."

Iterator<E> 인터페이스의 메서드 설명
boolean hasNext() 추가 요소가 있는지 확인
E next() 현재 요소를 반환하고 다음 요소로 이동합니다.
void remove() 현재 요소를 제거합니다.

"반복자를 사용하면 컬렉션의 모든 요소를 ​​연속적으로 가져올 수 있습니다. 반복자를 InputStream과 같은 것으로 생각하는 것이 더 논리적입니다. 모든 데이터가 있지만 작업은 순차적으로 출력하는 것입니다."

"   다음 () 메서드는 컬렉션의 다음 요소를 반환합니다."

" hasNext () 메서드는 요소가 더 있는지 확인하는 데 사용됩니다."

"그리고 제거 ()는 현재 요소를 제거합니다."

"질문 있나요?"

"메소드 이름이 이상한 이유는 무엇입니까? isEmpty() 및 getNextElement()가 아닌 이유는 무엇입니까?"

"그게 더 말이 되지 않을까요?"

"더 말이 되겠지만 이름은 반복자가 이전에 등장한 C++ 언어에서 유래했습니다."

"그렇구나. 계속하자."

"반복자 외에도 반복자를 지원하는 모든 컬렉션에서 구현해야 하는 Iterable 인터페이스도 있습니다. 다음과 같은 단일 메서드가 있습니다."

Iterable<T> 인터페이스의 메서드 설명
Iterator<T>iterator() 반복자 객체를 반환합니다.

"모든 컬렉션에서 이 메서드를 사용하여 반복자 개체가 해당 요소를 통과하도록 할 수 있습니다. TreeSet 의 모든 요소를 ​​살펴보겠습니다. "

TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}

"이와 같은 반복자를 사용하는 것은 그다지 편리하지 않습니다. 불필요하고 명백한 코드가 너무 많습니다. for -each 루프가 Java에 등장하면서 상황이 더 간단해졌습니다."

"이제 이 코드는 훨씬 간결하고 읽기 쉽습니다."

전에 후에
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}
TreeSet<String> set = new TreeSet<String>();

for(String item : set)
{
 System.out.println(item);
}

"이것은 동일한 코드입니다! 이터레이터는 두 경우 모두 사용됩니다."

"단지 for-each 루프 에서 사용이 숨겨져 있다는 것뿐입니다 . 오른쪽 코드에는 빨간색 텍스트가 전혀 없습니다. 반복자의 사용은 완전히 숨겨져 있습니다."

" for-each 루프는 반복자를 지원하는 모든 개체에 사용할 수 있습니다. 즉, 고유한 클래스를 작성하고 iterator ( ) 메서드를 추가하고 for-each 구문 에서 해당 개체를 사용할 수 있습니다 ."

"와! 물론 나만의 컬렉션과 이터레이터를 작성하고 싶지는 않지만 잠재 고객은 여전히 ​​유혹적입니다. 메모해 두겠습니다."

또한 자체 인터페이스가 있는 또 다른 인기 있는 반복자 유형이 있습니다. 목록에 대한 반복자, 즉 ListIterator 에 대해 이야기하고 있습니다 .

"구현에 관계없이 목록은 요소의 순서를 유지하므로 반복자를 통해 좀 더 편리하게 작업할 수 있습니다."

"다음은 ListIterator <E> 인터페이스 의 메소드입니다 ."

방법 설명
boolean hasNext() 앞에 요소가 더 있는지 확인합니다.
E next() 다음 요소를 반환합니다.
int nextIndex() 다음 요소의 인덱스를 반환
void set(E e) 현재 요소의 값을 변경합니다.
boolean hasPrevious() 뒤에 요소가 있는지 확인합니다.
E previous() 이전 요소를 반환
int previousIndex() 이전 요소의 인덱스를 반환
void remove() 현재 요소를 제거합니다.
void add(E e) 목록 끝에 요소를 추가합니다.

"즉, 여기서 우리는 앞뒤로 이동할 수 있습니다. 그리고 몇 가지 다른 작은 기능이 있습니다."

"흥미로운 일이군요. 어디에 쓰죠?"

"연결된 목록에서 앞뒤로 이동한다고 가정합니다. get 작업은 다소 느리지만 next() 작업은 매우 빠릅니다."

"흠. 당신은 나를 설득했습니다. 명심하겠습니다."

"고마워, 엘리!"