수색…


소개

java.util.Iterator 는, Iterator 디자인 패턴을 구현하는 객체의 표준 Java SE 인터페이스입니다. java.lang.Iterable 인터페이스는, 반복자를 제공 있는 오브젝트 용입니다.

비고

Java 배열은 Iterable를 구현하지 않지만, for each 루프를 사용하여 배열을 반복 할 수 있습니다. 반복은 백그라운드에서 액세스 할 수없는 색인을 사용하여 JVM에 의해 수행됩니다.

for 루프에서 Iterable 사용하기

Iterable<> 인터페이스를 구현하는 클래스는 for 루프에서 사용할 수 있습니다. 이것은 실제로 오브젝트에서 반복자를 가져 와서 모든 요소를 ​​순차적으로 가져 오는 구문 술식 입니다. 코드가 명확하고, 쓰기가 빠르며 오류가 발생하기 쉽습니다.

public class UsingIterable {

    public static void main(String[] args) {
        List<Integer> intList = Arrays.asList(1,2,3,4,5,6,7);
        
        // List extends Collection, Collection extends Iterable
        Iterable<Integer> iterable = intList;
        
        // foreach-like loop
        for (Integer i: iterable) {
            System.out.println(i);
        }
        
        // pre java 5 way of iterating loops
        for(Iterator<Integer> i = iterable.iterator(); i.hasNext(); ) {
            Integer item = i.next();
            System.out.println(item);
        }
    }
}

원시 반복자 사용

foreach 루프 (또는 "extended for loop")를 사용하는 것은 간단하지만 iterator를 직접 사용하는 것이 때로는 유용합니다. 예를 들어 쉼표로 구분 된 값을 출력하고 싶지만 마지막 항목에 쉼표를 사용하지 않으려면 다음을 입력하십시오.

List<String> yourData = //...
Iterator<String> iterator = yourData.iterator();
while (iterator.hasNext()){
    // next() "moves" the iterator to the next entry and returns it's value.
    String entry = iterator.next();
    System.out.print(entry);
    if (iterator.hasNext()){
        // If the iterator has another element after the current one:
        System.out.print(",");
    }
}

isLastEntry 변수를 사용하거나 루프 인덱스로 계산하는 것보다 훨씬 쉽고 명확합니다.

나만의 반복 생성.

모든 인터페이스와 마찬가지로 자신 만의 Iterable을 만들려면 인터페이스에 추상 메소드를 구현하면됩니다. Iterable 경우 iterator() 라고하는 하나만 있습니다. 그러나 그 리턴 타입 Iterator 는 그 자체로 3 가지 추상 메소드를 가진 인터페이스입니다. 일부 콜렉션과 연관된 반복자를 리턴하거나 사용자 정의 구현을 작성할 수 있습니다.

public static class Alphabet implements Iterable<Character> {

    @Override
    public Iterator<Character> iterator() {
        return new Iterator<Character>() {
            char letter = 'a';

            @Override
            public boolean hasNext() {
                return letter <= 'z';
            }

            @Override
            public Character next() {
                return letter++;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("Doesn't make sense to remove a letter");
            }
        };
    }
}

쓰다:

public static void main(String[] args) {
    for(char c : new Alphabet()) {
        System.out.println("c = " + c);
    }
}

새로운 Iterator 는 첫 번째 항목을 가리키는 상태로 있어야하며, next에 대한 각 호출은 다음 항목을 가리 키도록 상태를 업데이트합니다. hasNext() 는 반복자가 끝에 있는지 확인합니다. 반복자가 변경 가능한 컬렉션에 접속하고있는 경우, 반복자의 옵션의 remove() 메소드가 구현되어, 현재, 기본이되는 컬렉션으로부터 포인트 된 항목을 삭제할 수 있습니다.

반복자를 사용하여 요소 제거하기

Iterator.remove() 메소드에 대한 이전 호출에 의해 리턴 된 요소 제거하는 선택적 방법 Iterator.next() . 예를 들어, 다음 코드는 문자열 목록을 채운 다음 모든 빈 문자열을 제거합니다.

List<String> names = new ArrayList<>();
names.add("name 1");
names.add("name 2");
names.add("");
names.add("name 3");
names.add("");
System.out.println("Old Size : " + names.size());
Iterator<String> it = names.iterator();
while (it.hasNext()) {
  String el = it.next();
  if (el.equals("")) {
    it.remove();
  }
}
System.out.println("New Size : " + names.size());

출력 :

Old Size : 5
New Size : 3

위의 코드는 일반적인 컬렉션을 반복하는 동안 요소를 제거하는 안전한 방법입니다. 대신에 다음과 같이 컬렉션에서 요소를 제거하려고 시도합니다.

for (String el: names) {
    if (el.equals("")) {
        names.remove(el); // WRONG!
    }
}

이터레이터에 오류 빠른 반복자 의미를 제공하는 일반적인 컬렉션 (예 : ArrayList )은 ConcurrentModificationException 시킵니다.

remove() 메서드는 next() 호출 후에 만 ​​호출 될 수 있습니다 (한 번). next() 를 호출하기 전에 호출되었거나 next() 호출 후에 두 번 호출되는 경우 remove() 호출은 IllegalStateException 시킵니다.

remove 작업은 선택적 작업으로 설명됩니다. 즉, 모든 반복자가 허용하는 것은 아닙니다. 지원되지 않는 예제에는 변경 불가능한 콜렉션의 반복자, 콜렉션의 읽기 전용 뷰 또는 고정 된 크기의 콜렉션이 포함됩니다. 이터레이터가 제거를 지원하지 않을 때 remove() 가 호출되면 UnsupportedOperationException 을 던집니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow