logo

Java의 반복자

Java Cursor는 Collection 또는 Stream 객체의 요소를 하나씩 반복, 순회 또는 검색하는 데 사용되는 Iterator입니다. 이 글에서는 Java Iterator와 그것이 작동하는 방법에 대해 알아봅니다.

자바 커서

Java의 커서 유형

있다 아래에 언급된 대로 Java의 커서 세 개:

  1. 반복자
  2. 열거
  3. 목록반복자

메모: SplitIterator는 Iterator 전용 유형이므로 커서로 간주할 수도 있습니다.



1. 반복자

Java의 반복자는 수집 프레임워크 요소를 하나씩 검색합니다. 이것은 만능인 모든 Collection 객체에 적용할 수 있습니다. Iterator를 사용하면 읽기 및 제거 작업을 모두 수행할 수 있습니다. 요소 제거 기능이 추가된 Enumeration의 향상된 버전입니다.

Set, List, Queue, Deque 및 Map 인터페이스의 모든 구현 클래스와 같은 모든 Collection 프레임워크 구현 인터페이스의 요소를 열거할 때마다 Iterator를 사용해야 합니다. 반복자는 오직 전체 컬렉션 프레임워크에 대해 커서를 사용할 수 있습니다. 반복자 객체는 다음을 호출하여 생성할 수 있습니다. 반복자() Collection 인터페이스에 존재하는 메소드입니다.

통사론

Iterator itr = c.  iterator  ();>

메모: 여기서 c는 Collection 개체입니다. itr은 Iterator 인터페이스 유형이며 c를 참조합니다.

C# 튜토리얼

Java의 반복자 인터페이스 방법

반복자 인터페이스는 다음을 정의합니다. 아래에 나열된 방법:

1. 해즈넥스트(): 반복에 더 많은 요소가 있으면 true를 반환합니다.

public boolean hasNext();>

2. 다음(): 반복의 다음 요소를 반환합니다. 그것은 던진다 NoSuchElementException 더 이상 요소가 존재하지 않는 경우.

public Object next();>

3. 제거(): 반복에서 다음 요소를 제거합니다. 이 메서드는 next() 호출당 한 번만 호출할 수 있습니다.

public void remove();>

메모: 제거하다() 메소드는 다음과 같은 두 가지 예외를 발생시킬 수 있습니다.

  • 지원되지 않는 작업예외 : 이 반복자가 제거 작업을 지원하지 않는 경우
  • IllegalStateException : 다음 메소드가 아직 호출되지 않았거나 다음 메소드에 대한 마지막 호출 이후에 제거 메소드가 이미 호출된 경우.

Java Iterator는 내부적으로 어떻게 작동합니까?

이 섹션에서는 Java Iterator와 해당 메소드가 내부적으로 작동하는 방식을 이해하려고 합니다. 이 기능을 이해하기 위해 다음 LinkedList 개체를 살펴보겠습니다.

List cities = new LinkedList();  cities.add('G-1');  cities.add('G-2');  cities.add('G-3');  .  .  .  cities.add('G-n');>

이제 아래와 같이 List 객체에 Iterator 객체를 생성해 보겠습니다.

Iterator citiesIterator = cities.iterator();>

cityIteartor 반복자는 다음과 같습니다.

CSS에서 이미지 중앙 정렬
자바 반복자 1단계

여기서 Iterator의 커서는 목록의 첫 번째 요소 앞을 가리키고 있습니다.

이제 다음 코드 조각을 실행하겠습니다.

citiesIterator.hasNext(); citiesIterator.next();>
자바 반복자 2단계

위의 코드 조각을 실행하면 Iterator의 커서는 위 다이어그램에 표시된 대로 목록의 첫 번째 요소를 가리킵니다.

이제 다음 코드 조각을 실행하겠습니다.

citiesIterator.hasNext(); citiesIterator.next();>
자바 반복자 3단계

위의 코드 조각을 실행하면 Iterator의 커서는 위 다이어그램에 표시된 대로 목록의 두 번째 요소를 가리킵니다. 반복자의 커서를 목록의 마지막 요소에 도달하려면 이 프로세스를 수행하십시오.

Java 반복자 단계 n

마지막 요소를 읽은 후 아래 코드 조각을 실행하면 false 값이 반환됩니다.

citiesIterator.hasNext();>
마지막에 Java 반복자

Iterator의 Cursor는 List의 마지막 요소 이후를 가리키므로 hasNext() 메서드는 false 값을 반환합니다.

메모: 이러한 다이어그램을 모두 관찰한 후에는 아래 다이어그램과 같이 Java Iterator가 Forward Direction Iteration만 지원한다고 말할 수 있습니다. 그래서 단방향 커서라고도 합니다.

Java Iterator 작업

자바
// Java program to Demonstrate Iterator // Importing ArrayList and Iterator classes // from java.util package import java.util.ArrayList; import java.util.Iterator; // Main class public class Test { // Main driver method public static void main(String[] args) { // Creating an ArrayList class object // Declaring object of integer type ArrayList al = 새로운 ArrayList (); // 목록 반복 for (int i = 0; i< 10; i++) al.add(i); // Printing the elements in the List System.out.println(al); // At the beginning itr(cursor) will point to // index just before the first element in al Iterator itr = al.iterator(); // hasext() 메서드를 사용하여 // 목록에 단일 요소가 있을 때까지 // 조건이 true인 다음 요소를 확인합니다. while (itr.hasNext()) { // 커서를 다음 요소로 이동합니다. int i = itr.next( ); // 요소를 하나씩 가져오기 System.out.print(i + ' '); // 홀수 요소 제거 if (i % 2 != 0) itr.remove(); } // 다음 줄에 대한 명령 System.out.println(); // 객체 내부의 요소를 인쇄합니다. System.out.println(al); } }>

산출
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9 [0, 2, 4, 6, 8]>

SplitIterator

다른 Iterator와 마찬가지로 Spliterator는 소스의 요소를 순회하기 위한 것입니다. 소스는 다음과 같습니다. 수집 , IO 채널 또는 생성기 기능. 순차 순회 외에 효율적인 병렬 순회(병렬 프로그래밍)를 지원하기 위해 JDK 8에 포함되었습니다. Java Spliterator 인터페이스는 스트림을 더 작은 부분으로 나누는 내부 반복자입니다. 이러한 작은 부품은 병렬로 처리될 수 있습니다.

메모: 실제 프로그래밍에서는 Spliterator를 직접 사용할 필요가 전혀 없습니다. 일반적인 작업에서는 Java Iterator와 정확히 동일하게 작동합니다.

Java Iterator의 장점

  • 모든 Collection 클래스에 사용할 수 있습니다.
  • READ 및 REMOVE 작업을 모두 지원합니다.
  • 컬렉션 API용 범용 커서입니다.
  • 메소드 이름은 간단하고 사용하기 쉽습니다.

Java Iterator의 한계

또한 Iterator에는 다음과 같은 특정 제한 사항이 있습니다.

  • CRUD 작업에서는 CREATE 및 UPDATE 작업을 지원하지 않습니다.
  • 단방향 반복자인 순방향 반복만 지원합니다.
  • Spliterator와 비교하면 반복 요소 병렬을 지원하지 않습니다. 즉 순차 반복만 지원한다는 의미입니다.
  • Spliterator와 비교하면 대량의 데이터를 반복하는 데 더 나은 성능을 지원하지 않습니다.

2. 열거

레거시 컬렉션(벡터, 해시테이블)의 요소를 가져오는 데 사용되는 인터페이스입니다. 열거형은 JDK 1.0의 첫 번째 반복자이며 나머지는 JDK 1.2에 더 많은 기능이 포함되어 있습니다. 열거형은 입력 스트림을 지정하는 데에도 사용됩니다. 시퀀스입력스트림 . 다음을 호출하여 Enumeration 객체를 생성할 수 있습니다. 강요() 모든 벡터 객체에 대한 벡터 클래스의 메서드

통사론

// Here 'v' is an Vector class object. e is of // type Enumeration interface and refers to 'v' Enumeration e =   v  .  elements  ();>

있다 Enumeration 인터페이스의 메소드는 다음과 같습니다.

1. 공개 부울 hasMoreElements(): 이 메서드는 이 열거형에 더 많은 요소가 포함되어 있는지 여부를 테스트합니다.

2. 공개 객체 nextElement(): 이 메서드는 이 열거형의 다음 요소를 반환합니다. 더 이상 요소가 없으면 NoSuchElementException이 발생합니다.

자바
// Java program to demonstrate Enumeration // Importing Enumeration and Vector classes // from java.util package import java.util.Enumeration; import java.util.Vector; // Main class public class Test { // Main driver method public static void main(String[] args) { // Creating a vector object Vector v = new Vector(); // Iterating over vector object for (int i = 0; i < 10; i++) v.addElement(i); // Printing elements in vector object System.out.println(v); // At beginning e(cursor) will point to // index just before the first element in v Enumeration e = v.elements(); // Checking the next element availability where // condition holds true till there is a single // element // remaining in the List while (e.hasMoreElements()) { // Moving cursor to next element int i = (Integer)e.nextElement(); // Print above elements in object System.out.print(i + ' '); } } }>

산출
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9>

열거에는 다음과 같은 특정 제한 사항이 있습니다.

  • 열거 대상은 다음과 같습니다. 유산 클래스(벡터, 해시테이블)만 해당됩니다. 따라서 범용 반복자가 아닙니다.
  • 열거를 사용하여 제거 작업을 수행할 수 없습니다.
  • 순방향 반복만 가능합니다.

Java 열거형과 반복자의 유사점

  • 둘 다 Java 커서입니다.
  • 둘 다 개체 요소 컬렉션을 하나씩 반복하는 데 사용됩니다.
  • 둘 다 READ 또는 검색 작업을 지원합니다.
  • 둘 다 단방향 Java 커서이며 이는 순방향 반복만 지원함을 의미합니다.

Java 열거형과 반복자의 차이점

다음 표에서는 Java Enumeration과 Iterator의 차이점을 설명합니다.

열거반복자
자바 1.0에서 도입자바 1.2에서 도입됨
레거시 인터페이스레거시 인터페이스가 아님
레거시 컬렉션 클래스만 반복하는 데 사용됩니다.모든 Collection 클래스에 사용할 수 있습니다.
READ 작업만 지원합니다.READ 및 DELETE 작업을 모두 지원합니다.
유니버설 커서가 아닙니다.범용 커서입니다.
메소드 이름이 길다.간단하고 사용하기 쉬운 메소드 이름.

3. 목록반복자

ArrayList, LinkedList 등과 같은 목록 컬렉션 구현 클래스에만 적용 가능합니다. 양방향 반복을 제공합니다. ListIterator는 List의 요소를 열거할 때 사용해야 합니다. 이 커서는 반복자보다 더 많은 기능(메서드)을 가지고 있습니다. ListIterator 객체는 다음을 호출하여 생성할 수 있습니다. 목록반복자() List 인터페이스에 존재하는 메소드입니다.

통사론

ListIterator ltr = l.  listIterator  ();>

메모: 여기서 l은 List 객체이고 ltr은 유형입니다. ListIterator 인터페이스이며 l을 참조합니다. ListIterator 인터페이스는 Iterator 인터페이스를 확장합니다. 따라서 Iterator 인터페이스의 세 가지 메소드를 모두 ListIterator에 사용할 수 있습니다. 또한, 더 많은 방법.

1. 정방향

1.1 해즈다음(): 반복에 더 많은 요소가 있으면 true를 반환합니다.

public boolean hasNext();>

1.2 다음(): Iterator의 next() 메소드와 동일합니다. 반복의 다음 요소를 반환합니다.

public Object next();>

1.3 nextIndex(): 목록 반복자가 목록 끝에 있는 경우 다음 요소 인덱스 또는 목록 크기를 반환합니다.

public int nextIndex();>

2. 역방향

2.1 hasPrevious(): 뒤로 탐색하는 동안 반복에 더 많은 요소가 있으면 true를 반환합니다.

public boolean hasPrevious();>

2.2 이전(): 반복에서 이전 요소를 반환하고 던질 수 있습니다. NoSuchElementException 더 이상 요소가 존재하지 않는 경우.

public Object previous();>

2.3 이전 인덱스(): 이전 요소 인덱스를 반환하거나 목록 반복자가 목록의 시작 부분에 있으면 -1을 반환합니다.

피트 데이비슨 나이
public int previousIndex();>

3. 기타 방법

3.1 제거(): Iterator의 Remove() 메소드와 동일합니다. 반복에서 다음 요소를 제거합니다.

public void remove();>

3.2 세트(객체 obj): next() 또는 이전()에서 반환된 마지막 요소를 지정된 요소로 바꿉니다.

public void set(Object obj);>

3.3 추가(객체 obj): next()에서 반환할 요소 앞의 위치에 지정된 요소를 목록에 삽입합니다.

public void add(Object obj);>

분명히, 세 가지 방법은 목록반복자 Iterator에서 상속됩니다( 해즈다음() , 다음() , 그리고 제거하다() ) 두 인터페이스 모두에서 정확히 동일한 작업을 수행합니다. 그만큼 has이전() 이전 작업은 다음과 정확히 유사합니다. 해즈다음() 그리고 다음() . 전자의 연산은 (암시적) 커서 앞의 요소를 참조하는 반면, 후자의 연산은 커서 뒤의 요소를 참조합니다. 이전 작업은 커서를 뒤로 이동하고 다음 작업은 커서를 앞으로 이동합니다.

ListIterator에는 현재 요소가 없습니다. 커서 위치는 항상 호출에 의해 반환되는 요소 사이에 있습니다. 이전의() 호출에 의해 반환되는 요소 다음().

1 세트() 메소드는 4개의 예외를 발생시킬 수 있습니다.

우분투 어떤 명령
  • 지원되지 않는 작업예외: 이 목록 반복자가 설정 작업을 지원하지 않는 경우
  • 클래스캐스트예외: 지정된 요소의 클래스로 인해 이 목록에 추가되지 않는 경우
  • IllegalArgumentException: 지정된 요소의 일부 측면으로 인해 이 목록에 추가되지 않는 경우
  • IllegalState예외: 다음이나 이전이 모두 호출되지 않았거나 다음 또는 이전에 대한 마지막 호출 이후에 제거 또는 추가가 호출된 경우

2. 추가() 메소드는 3개의 예외를 발생시킬 수 있습니다.

  • 지원되지 않는 작업예외: 이 목록 반복자가 add 메소드를 지원하지 않는 경우
  • 클래스캐스트예외: 지정된 요소의 클래스로 인해 이 목록에 추가되지 않는 경우
  • IllegalArgumentException: 이 요소의 일부 측면으로 인해 이 목록에 추가되지 않는 경우

자바
// Java program to demonstrate ListIterator // Importing ArrayList and List iterator classes // from java.util package import java.util.ArrayList; import java.util.ListIterator; // Main class public class Test { // Main driver method public static void main(String[] args) { // Creating an object of ArrayList class ArrayList al = new ArrayList(); // Iterating over Arraylist object for (int i = 0; i < 10; i++) // Adding elements to the Arraylist object al.add(i); // Print and display all elements inside object // created above System.out.println(al); // At beginning ltr(cursor) will point to // index just before the first element in al ListIterator ltr = al.listIterator(); // Checking the next element availability while (ltr.hasNext()) { // Moving cursor to next element int i = (Integer)ltr.next(); // Getting even elements one by one System.out.print(i + ' '); // Changing even numbers to odd and // adding modified number again in // iterator if (i % 2 == 0) { // Change to odd i++; // Set method to change value ltr.set(i); // To add ltr.add(i); } } // Print and display statements System.out.println(); System.out.println(al); } }>

산출
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9 [1, 1, 1, 3, 3, 3, 5, 5, 5, 7, 7, 7, 9, 9, 9]>

메모: 마찬가지로 ListIterator에는 특정 제한 사항이 있습니다. . 가장 강력한 반복자이지만 List 구현 클래스에만 적용 가능하므로 범용 반복자는 아닙니다.

중요사항

  1. 처음에는 모든 반복기 참조가 컬렉션의 첫 번째 요소 인덱스 바로 앞의 인덱스를 가리킨다는 점에 유의하세요.
  2. Enumeration, Iterator, ListIterator 객체는 인터페이스이기 때문에 생성하지 않습니다. 우리는 객체를 생성하기 위해 elements(), iterator(), listIterator()와 같은 메소드를 사용합니다. 이 메소드에는 익명이 있습니다. 내부 클래스 이는 각각의 인터페이스를 확장하고 이 클래스 객체를 반환합니다.

메모: 그만큼 $ 참조 클래스 이름의 기호는 내부 클래스의 개념을 사용하여 이러한 클래스 객체가 생성되었음을 증명합니다.

이는 아래 코드로 확인할 수 있습니다. 내부 클래스에 대한 자세한 내용은 다음을 참조하세요.

자바
// Java program to demonstrate iterators references // Importing required classes from java.util package import java.util.Enumeration; import java.util.Iterator; import java.util.ListIterator; import java.util.Vector; // Main class public class GFG { // Main driver method public static void main(String[] args) { // Creating an object of Vector class Vector v = new Vector(); // Creating three iterators Enumeration e = v.elements(); Iterator itr = v.iterator(); ListIterator ltr = v.listIterator(); // Print class names of iterators // using getClass() and getName() methods System.out.println(e.getClass().getName()); System.out.println(itr.getClass().getName()); System.out.println(ltr.getClass().getName()); } }>

산출
java.util.Vector java.util.Vector$Itr java.util.Vector$ListItr>

설명

Java에서 반복자는 개체 컬렉션을 하나씩 탐색하는 데 사용되는 인터페이스입니다. 배열, 목록, 세트 및 맵을 포함한 컬렉션 기반 데이터 구조를 반복하는 데 사용됩니다.

반복자에는 컬렉션을 탐색하는 데 사용되는 세 가지 주요 메서드가 있습니다.

  • hasNext() – 이 메서드는 컬렉션에 반복할 수 있는 다른 요소가 있는지 확인합니다.
  • next() – 이 메서드는 컬렉션의 다음 요소를 반환합니다.
  • 제거() – 이 메서드는 컬렉션에서 현재 요소를 제거합니다.

Iterator 인터페이스는 Java Collection Framework의 일부이며 다양한 유형의 컬렉션을 나타내는 클래스에 의해 구현됩니다.

프로그램

자바
import java.util.ArrayList; import java.util.Iterator; public class IteratorExample { public static void main(String[] args) { ArrayList이름 = 새 ArrayList(); names.add('앨리스'); names.add('밥'); names.add('찰리'); names.add('데이비드'); // 이름 목록 Iterator에 대한 반복자 생성반복자 = names.iterator(); // 반복자를 사용하여 이름 목록을 반복합니다. while (iterator.hasNext()) { String name = iterator.next(); System.out.println(이름); } } }>

산출
Alice Bob Charlie David>

이 예에서는 문자열의 ArrayList를 만들고 여기에 네 개의 이름을 추가했습니다. 그런 다음 ArrayList 클래스의 iterator() 메서드를 사용하여 목록에 대한 반복자를 만들었습니다. hasNext() 메서드를 사용하여 목록에 반복할 요소가 더 있는지 확인하고 next() 메서드를 사용하여 목록의 다음 요소를 가져왔습니다. System.out.println() 메소드를 사용하여 각 요소를 인쇄했습니다.

반복자를 사용하여 컬렉션을 순회하는 것은 컬렉션을 반복하는 편리하고 효율적인 방법입니다. 컬렉션의 내부 구조를 모르더라도 컬렉션을 반복할 수 있기 때문입니다. 또한 컬렉션을 반복하는 동안 컬렉션에서 요소를 제거할 수도 있습니다.

Java에서 Iterator의 장점:

  • Iterator는 기본 구현을 노출하지 않고 컬렉션을 탐색할 수 있는 간단하고 사용하기 쉬운 인터페이스입니다.
  • Iterator는 특히 대량의 데이터가 있는 경우 컬렉션을 반복하는 효율적인 방법입니다.
  • Iterator는 동시 수정 예외를 발생시키지 않고 반복 중에 컬렉션에서 요소를 제거하는 안전한 방법을 제공합니다.
  • Iterator 인터페이스는 Java의 모든 컬렉션 클래스에 의해 구현되므로 동일한 코드를 사용하여 다양한 유형의 컬렉션을 반복할 수 있습니다.

Java Iterator의 단점:

아래와 같이 Java에서 Iterator를 사용하면 몇 가지 단점이 있습니다.

  • Iterator는 단방향 인터페이스입니다. 즉, 컬렉션을 통해서만 앞으로 이동할 수 있습니다. 뒤로 이동하거나 특정 요소로 이동할 수 없습니다.
  • Iterator는 스레드로부터 안전하지 않으므로 적절한 동기화 없이는 다중 스레드 환경에서 컬렉션을 반복하는 데 사용할 수 없습니다.
  • Iterator는 요소 제거 외에 컬렉션을 반복하는 동안 요소를 수정하는 메커니즘을 제공하지 않습니다. 요소를 수정해야 하는 경우 ListIterator와 같은 다른 인터페이스나 간단한 for 루프를 사용해야 합니다.