Java의 Iterator와 ListIterator가 요소 사이를 가리키는 이유는 무엇입니까?


9

ListIterator에 대한 Javadoc 은 다음과 같이 말합니다.

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

Java가 ListIterator현재 요소가 아닌 요소 사이를 가리 키도록 구현 된 이유는 무엇 입니까? 반복적으로 호출 할 때이 클라이언트 코드가 덜 쉽게 읽을 것 같다 getNext(), getPrevious()내가 선택을위한 좋은 이유가 있어야합니다 가정, 그래서.

사이드 참고로, 난 그냥 쓴 작은 도서관이라고 peekable-ArrayList를 확장 ArrayList, Iterator그리고 ListIterator그건 제공 peekAtNext()peekAtPrevious()방법은 다음과 같이 구현 :

  @Override public synchronized T peekAtNext() {
     T t = next();
     previous();
     return t;
  }


고마워 Kevin! SO에 대한 후속 질문을 게시했습니다 : PeekingIterator와 함께 Guava의 ForwardingListIterator를 사용할 수 있습니까?
glenviewjeff

답변:


12

내가 알 수있는 한, 그 이유는 인용하지 않은 javadoc 부분에서 찾을 수 있습니다 (내 강조).

프로그래머가 목록을 어느 방향으로나 이동할 수 있도록하는 목록의 반복자입니다. 반복하는 동안 목록을 수정 하십시오.

의도 된 목적은 목록을 수정하는 동안 사용을 허용하는 것입니다. 가능한 수정은 분명히 요소의 제거 를 포함 합니다.

이제 current()반복자가 현재 요소라는 개념을 가지고 있다고 가정하고 반복자에 대한 요소를 제거하면 어떻게 될지 생각해보십시오 . 이 맥락에서 현재 요소 의 개념없이 그것을 구현하는 방법 은 나에게 매우 합리적입니다. 그러므로 반복자는 요소 제거에 대해 걱정할 필요가 없기 때문입니다.


이다 중요한 스레드 안전을 위해 인터페이스 구현을 필요로하지 않는 자바 독을 주목.

  • 이 때문에 다른 스레드에서 수행 된 수정의 올바른 처리를 기 대해서는 안됩니다 . 구현시 JSR 133에 따라 Java 메모리 모델에 지정된대로 액세스를 동기화하고 가시성을 보장하는 추가 수단을 제공해야합니다 .

ListIterator가 할 수있는 것은 반복 할 때 동일한 스레드에서 수행 된 수정을 처리하는 것입니다. 모든 반복자가 그런 것은 아닙니다. ConcurrentModificationException javadocs는 특히 이것에 대해 경고합니다.

...이 예외가 항상 다른 스레드에 의해 객체가 수정되었음을 나타내는 것은 아닙니다. 단일 스레드가 객체의 계약을 위반하는 일련의 메소드 호출을 발행하면 객체가이 예외를 발생시킬 수 있습니다. 예를 들어, 스레드가 페일 빠른 반복기를 사용하여 콜렉션을 반복하는 동안 콜렉션이 직접 수정하면 반복자는이 예외를 처리합니다.


1
그것은 또한 당신이 별도 필요하지 않습니다 의미 insertBeforeinsertAfter그 문제가로서 큰로서 아니에요 있지만 remove.
Karl Bielefeldt

1
그렇다면 현재 요소를 동시에 제거하고 액세스 할 수있는 문제입니까? 이것은 동시에 호출하는 것과 동등한 문제가 next()아닐까요? remove()synchronizedgetCurrent()입니다. 뭔가 빠졌습니까?
glenviewjeff

@glenviewjeff 그것은 매우 좋은 관찰입니다. 또한 CME가 어떻게 처리 될 수 있는지 궁금합니다. 수정을 허용하려는 의도는 그러한 우려를 불러 일으 킵니다. 더 깊이 파고 들어야한다고 생각합니다. 나는 99.99 % 확신 어쩌면 그것은 단지 동일한 스레드 (모든 반복자는, 그 능력이 당신이 알고있는)에서 수행 동시 개조 처리 할 수있는, 스레드 안전으로 구성 아니에요거야
모기

관심이 있다면 내 편집을 참조하십시오. ArrayList이를 위해 확장 프로그램을 구현하고 패키지했습니다 .
glenviewjeff

트윗 담아 가기 구현에서 next () 및 previous ()도 동기화됩니까? 물어 때문에하지 않으면, 다른 스레드 수 "드릴"현재의 중간 ()에 예상치 못한 이동 좋아, 그것을 행동하게하지 클라이언트가 기대하는 꽤처럼 ... 추가 등의 방법 () 아마도 동기화를 필요
gnat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.