문제

방금 Java Collections Framework가 연결된 목록의 데이터 구조를 구현하는 방법에 대해 배웠습니다.제가 이해한 바로는, Iterators 목록과 같은 데이터 구조의 항목을 탐색하는 방법입니다.이 인터페이스를 사용하는 이유는 무엇입니까?방법은 왜 hasNext(), next() 그리고 remove() 데이터 구조 구현 자체에 직접 코딩되지 않았습니까?

자바 웹사이트에서: 링크 텍스트

공용 인터페이스 Iterator<E>

컬렉션 위의 반복자.Ierator는 Java Collections 프레임 워크에서 열거를 대신합니다.반복자는 두 가지 방식으로 열거와 다릅니다.

  • 반복자를 통해 발신자는 잘 정의 된 의미로 반복하는 동안 기본 컬렉션에서 요소를 제거 할 수 있습니다.
  • 메소드 이름이 개선되었습니다.
이 인터페이스는 Java Collections Framework의 회원입니다.

인터넷 검색을 시도해 보았지만 명확한 답을 찾을 수 없는 것 같습니다.Sun이 왜 이를 사용하기로 결정했는지 알려줄 수 있는 사람이 있습니까?디자인이 좋아진 탓일까요?보안이 강화되었나요?좋은 OO 연습이요?

어떤 도움이라도 대단히 감사하겠습니다.감사해요.

도움이 되었습니까?

해결책

이 인터페이스를 사용하는 이유는 무엇입니까?

클라이언트 프로그래머가 모든 종류의 컬렉션을 반복할 수 있는 기본 작업을 지원하기 때문입니다(참고:반드시 그런 것은 아니다 Collection 에서 Object 감각).

방법이 왜...데이터 구조 구현 자체에 직접 코딩되지 않습니까?

그들은 단지 비공개로 표시되어 있어서 접근할 수 없고 장난칠 수 없습니다.더 구체적으로:

  • 구현하거나 서브클래싱할 수 있습니다. Iterator 반복되는 실제 객체를 변경하지 않고도 표준 객체가 수행하지 않는 작업을 수행합니다.
  • 순회할 수 있는 객체는 순회 메서드, 특히 고도로 전문화된 메서드로 인터페이스를 복잡하게 만들 필요가 없습니다.
  • 나눠주셔도 됩니다 Iterators 원하는 클라이언트 수에 관계없이 각 클라이언트는 자신의 시간과 속도로 이동할 수 있습니다.
  • 자바 Iterators 특히 java.util 패키지의 경우 이를 지원하는 저장소가 여전히 수정된 경우 예외가 발생합니다. Iterator 밖으로.이 예외를 통해 Iterator 이제 잘못된 개체를 반환할 수 있습니다.

간단한 프로그램의 경우에는 이 중 어느 것도 가치가 없어 보입니다.하지만 그것들을 유용하게 만드는 종류의 복잡성은 당신에게 빨리 다가올 것입니다.

다른 팁

물어:"hasNext(), next() 및 Remove() 메소드가 데이터 구조 구현 자체에 직접 코딩되지 않은 이유는 무엇입니까?"

Java 컬렉션 프레임워크는 컬렉션 자체에 외부화된 Iterator 인터페이스를 정의하기로 선택합니다.일반적으로 모든 Java 컬렉션은 Iterable 인터페이스, Java 프로그램이 호출합니다. iterator 루프에서 사용할 수 있도록 자체 반복자를 만듭니다.다른 사람들이 지적했듯이 Java 5에서는 for-each 루프를 사용하여 반복자를 직접 사용할 수 있습니다.

반복자를 컬렉션으로 외부화하면 클라이언트가 컬렉션을 반복하는 방법을 제어할 수 있습니다.이것이 유용하다고 생각되는 한 가지 사용 사례는 인터넷의 모든 웹 페이지와 같이 색인을 생성할 무제한 컬렉션이 있는 경우입니다.

고전적인 GoF 책에서는 내부 반복자와 외부 반복자의 대조가 아주 명확하게 설명되어 있습니다.

근본적인 문제는 반복, 반복자 또는 반복자를 사용하는 클라이언트를 제어하는 ​​당사자를 결정하는 것입니다.클라이언트가 반복을 제어하는 ​​경우 반복자를 외부 반복자라고 하고, 반복자가 이를 제어하는 ​​경우 반복자를 내부 반복자라고 합니다.외부 반복기를 사용하는 클라이언트는 순회를 진행하고 반복기에서 명시적으로 다음 요소를 요청해야 합니다.대조적으로, 클라이언트는 내부 반복자에게 수행할 작업을 전달하고 반복자는 해당 작업을 모든 요소에 적용합니다.

외부 반복자는 내부 반복자보다 더 유연합니다.예를 들어 두 컬렉션이 외부 반복자와 동일한지 비교하는 것은 쉽지만 내부 반복자에서는 사실상 불가능합니다.그러나 반면에 내부 반복자는 반복 논리를 정의하므로 사용하기가 더 쉽습니다.

내부 반복자가 어떻게 작동하는지에 대한 예는 Ruby의 Enumerable 다음과 같은 내부 반복 방법이 있는 API each.Ruby에서는 코드 블록(예:클로저)를 내부 반복자에 추가하여 컬렉션이 자체 반복을 처리할 수 있도록 합니다.

포인터와 컬렉션을 분리하는 것이 중요합니다.반복자는 컬렉션의 특정 위치를 가리키므로 컬렉션의 필수 부분이 아닙니다.예를 들어 이 방법으로 동일한 컬렉션에 대해 여러 반복자를 사용할 수 있습니다.

이 분리의 단점은 반복자가 반복하는 컬렉션의 변경 사항을 인식하지 못한다는 것입니다.따라서 컬렉션의 구조를 변경할 수 없으며 반복자가 "불만" 없이 작업을 계속할 것으로 기대할 수 없습니다.

사용하여 Iterator 인터페이스를 사용하면 메서드를 구현하는 모든 클래스가 반복자 역할을 할 수 있습니다.Java에서 인터페이스의 개념은 어떤 방식으로든 클래스에서 특정 기능을 제공해야 하는 계약상 의무를 갖는 것입니다. implements 인터페이스에서 요구하는 방식으로 작동합니다.유효한 클래스가 되기 위해서는 계약상의 의무가 충족되어야 하므로 해당 클래스를 참조하는 다른 클래스는 implements 인터페이스를 제공하므로 클래스에 특정 기능이 있다는 것을 알 수 있으므로 안심할 수 있습니다.

이 예에서는 메서드를 구현하는 대신(hasNext(), next(), remove())에서 LinkedList 수업 그 자체, LinkedList 수업은 그것을 선언합니다 implements 그만큼 Iterator 인터페이스를 통해 다른 사람들이 알 수 있도록 LinkedList 반복자로 사용할 수 있습니다.차례로, LinkedList 클래스는 다음의 메소드를 구현합니다. Iterator 인터페이스(예: hasNext())이므로 반복자처럼 작동할 수 있습니다.

즉, 인터페이스 구현은 특정 클래스가 주장하는 대로 되기 위해 필요한 것이 무엇인지 다른 사람에게 알리기 위한 객체 지향 프로그래밍 개념입니다.

이 개념은 인터페이스를 구현하는 클래스에 의해 구현되어야 하는 메서드를 가짐으로써 적용됩니다.이렇게 하면 해당 클래스를 구현하는 클래스를 사용하려는 다른 클래스가 Iterator Iterator가 가져야 하는 메소드를 실제로 갖게 될 인터페이스입니다. hasNext().

또한 Java에는 다중 상속이 없으므로 인터페이스를 사용하여 해당 기능을 에뮬레이트할 수 있습니다.여러 인터페이스를 구현하면 일부 기능을 상속하는 하위 클래스인 클래스를 가질 수 있을 뿐만 아니라 인터페이스를 구현하여 다른 기능을 "상속"할 수도 있습니다.한 가지 예는 다음과 같습니다. LinkedList 클래스라는 ReversibleLinkedList 역순으로 반복할 수 있으므로 다음과 같은 인터페이스를 만들 수 있습니다. ReverseIterator 그리고 그것이 previous() 방법.이후 LinkedList 이미 구현 Iterator, 새로운 가역 목록은 두 가지를 모두 구현했을 것입니다 Iterator 그리고 ReverseIterator 인터페이스.

인터페이스에 대한 자세한 내용은 다음에서 확인할 수 있습니다. 인터페이스란 무엇입니까? Sun의 Java Tutorial에서 발췌.

인터레이터의 여러 인스턴스를 동시에 사용할 수 있습니다.기본 데이터에 대한 로컬 커서로 접근하십시오.

지금:구체적인 구현보다 인터페이스를 선호하면 결합이 느슨해집니다.

반복자 디자인 패턴을 찾아보세요. 여기에서: http://en.wikipedia.org/wiki/Iterator

데이터 구조가 아닌 것을 반복할 수 있기 때문입니다.서버에서 결과를 가져오는 네트워크 애플리케이션이 있다고 가정해 보겠습니다.해당 결과 주위에 Iterator 래퍼를 반환할 수 있으며 스트리밍해 보세요 Iterator 객체를 허용하는 표준 코드를 통해.

좋은 MVC 디자인의 핵심 부분이라고 생각하십시오.데이터는 모델에서 가져와야 합니다(예:데이터 구조)를 어떻게든 뷰에 추가합니다.Iterator를 중개자로 사용하면 모델 구현이 노출되지 않습니다.LinkedList를 메모리에 유지하거나, 암호 해독 알고리즘에서 정보를 가져오거나, JDBC 호출을 래핑할 수 있습니다.뷰는 Iterator 인터페이스에만 관심이 있기 때문에 뷰에는 중요하지 않습니다.

반복자 사용의 장점과 단점을 논의한 흥미로운 논문:

http://www.sei.cmu.edu/pacc/CBSE5/Sridhar-cbse5-final.pdf

나는 그것이 좋은 OO 연습이라고 생각합니다.모든 종류의 반복자를 처리하는 코드가 있을 수 있으며, 자신만의 데이터 구조를 만들거나 반복자 인터페이스를 구현하는 일반 클래스를 만들 수도 있습니다.그 뒤에 어떤 종류의 구현이 있는지 걱정할 필요가 없습니다.

M2C만 알고 계신다면:다음과 같은 상황에서는 반복자 인터페이스를 직접 사용하는 것을 피할 수 있습니다. 각각 루프로 충분합니다.

궁극적으로 Iterator는 수많은 데이터 구조에 적용할 수 있는 제어 추상화를 캡처하기 때문입니다.범주 이론에 관심이 있다면 이 문서를 보고 깜짝 놀라게 될 것입니다. 반복자 패턴의 본질.

글쎄요, 첫 번째 중요 항목에서는 동시성 위반에 대해 컬렉션을 잠글 필요가 없는 다중 스레드(또는 문제가 있는 경우 단일 스레드) 애플리케이션을 허용하는 것 같습니다.예를 들어 .NET에서는 IEnumerable에서 잠그거나 상속하고 메서드를 재정의하지 않고(예외가 발생함) 컬렉션(또는 목록 또는 IEnumerable)을 동시에 열거하고 수정할 수 없습니다.

Iterator는 단순히 항목 컬렉션을 검토하는 일반적인 방법을 추가합니다.좋은 기능 중 하나는 반복 중인 목록에서 요소를 제거할 수 있는 i.remove()입니다.일반적으로 목록에서 항목을 제거하려고 하면 이상한 효과가 발생하거나 예외가 발생합니다.

인터페이스는 그것을 구현하는 모든 것에 대한 계약과 같습니다.기본적으로 말씀하시네요..반복자를 구현하는 모든 것은 동일한 방식으로 작동하는 이러한 메서드를 갖도록 보장됩니다.코드에서 처리하는 데 관심이 있는 것이 반복자 유형의 전부인 경우 이를 사용하여 반복자 유형을 전달할 수도 있습니다.(어떤 유형의 목록인지는 신경 쓰지 않을 수도 있습니다.Iterator를 전달하기만 하면 됩니다.) 이 모든 메소드를 컬렉션에 독립적으로 넣을 수 있지만 이들이 동일하게 작동하거나 동일한 이름과 서명을 갖는다고 보장할 수는 없습니다.

반복자는 Java에서 사용할 수 있는 많은 디자인 패턴 중 하나입니다.디자인 패턴은 편리한 빌딩 블록, 스타일, 코드/구조의 사용법으로 생각할 수 있습니다.

Iterator 디자인 패턴에 대한 자세한 내용을 보려면 Iterator 및 기타 여러 디자인 패턴에 대해 설명하는 이 웹 사이트를 확인하세요.다음은 Iterator 사이트의 일부입니다. http://www.patterndepot.com/put/8/Behavioral.html

반복자는 디자인 패턴 중 가장 단순하고 가장 자주 사용되는 것 중 하나입니다.반복자 패턴을 사용하면 해당 데이터의 내부 표현의 세부 사항을 알지 못하고 표준 인터페이스를 사용하여 데이터 수집을 통해 이동할 수 있습니다.또한 일부 특수 처리를 수행하고 데이터 수집의 지정된 요소 만 반환하는 특수 반복자를 정의 할 수도 있습니다.

반복자는 모든 종류의 컬렉션에 대해 사용할 수 있습니다.기본 구현에 관계없이 항목 컬렉션에 대해 알고리즘을 정의할 수 있습니다.이는 목록, 집합, 문자열, 파일, 배열 등을 처리할 수 있음을 의미합니다.

지금부터 10년 후에는 List 구현을 더 나은 구현으로 변경할 수 있으며 알고리즘은 이에 대해 여전히 원활하게 실행됩니다.

Iterator는 Java에서 컬렉션을 처리할 때 유용합니다.

사용 각각 컬렉션, 배열 또는 목록을 반복하기 위한 loop(Java1.5)입니다.

java.util.Iterator 인터페이스는 Java 컬렉션 프레임워크에서 컬렉션을 반복하면서 컬렉션을 수정하는 데 사용됩니다.전체 컬렉션을 깔끔하게 반복하려면 대신 for-each를 사용하세요. 하지만 Iterator의 장점은 다음과 같은 기능을 제공한다는 것입니다.선택적 제거() 작업이며 add() 및 set() 작업도 제공하는 List Iterator 인터페이스에 더 좋습니다.이 두 인터페이스를 모두 사용하면 컬렉션을 반복하고 동시에 구조적으로 변경할 수 있습니다.for-each를 사용하여 컬렉션을 반복하는 동안 컬렉션을 수정하려고 하면 ConcurrentModificationException이 발생합니다. 일반적으로 컬렉션이 예기치 않게 수정되었기 때문입니다!

ArrayList 클래스를 살펴보세요

ITR 및 Listitr라는 2 개의 개인 클래스 (내부 클래스)가 있습니다.

Iterator 및 ListIterator 인터페이스를 각각 구현합니다.

공개 클래스 ArrayList.....{ //인클로징 클래스

  private class Itr implements Iterator<E> {

        public E next() {
            return ArrayList.this.get(index++); //rough, not exact
        }

        //we have to use ArrayList.this.get() so the compiler will
        //know that we are referring to the methods in the 
        //enclosing ArrayList class

        public void remove() {
            ArrayList.this.remove(prevIndex);
        }

        //checks for...co mod of the list
        final void checkForComodification() {  //ListItr gets this method as well
             if (ArrayList.this.modCount != expectedModCount) { 
                 throw new ConcurrentModificationException();
             }
        }
  }

  private class ListItr extends Itr implements ListIterator<E> {
         //methods inherted....
        public void add(E e) {
            ArrayList.this.add(cursor, e);
        }

        public void set(E e) {
            ArrayList.this.set(cursor, e);
        }
  }

}

메소드 iterator () 및 listiterator ()를 호출 할 때 개인 클래스 ITR 또는 Listitr의 새로운 인스턴스를 반환하고 이러한 내부 클래스는 Enclosing ArrayList 클래스 내에 있으므로 동시 계수를 트리거하지 않고 ArrayList를 자유롭게 수정할 수 있습니다. , arraylist 클래스의 set () add () 또는 remove () 메소드를 통해 목록을 동시에 변경하지 않는 한

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top