Java 집합 Iterator 교체의 실현 방법

5412 단어 java집합iterator
우리는 JDK가 제공하는 교체 인터페이스를 자주 사용하여 Java 집합의 교체를 진행한다.

Iterator iterator = list.iterator();
while(iterator.hasNext()){
String string = iterator.next();
//do something
}
교체는 사실 우리는 간단하게 반복이라고 이해할 수 있다. 이것은 각종 용기 안의 모든 대상을 표준화하는 방법류이고 이것은 매우 전형적인 디자인 모델이다.Iterator 모드는 집합 클래스를 훑어보는 데 사용되는 표준 접근 방법입니다.그것은 접근 논리를 서로 다른 유형의 집합 클래스에서 추상화하여 클라이언트에게 집합의 내부 구조를 노출하는 것을 피할 수 있다.교체기가 없을 때 우리는 모두 이렇게 처리한다.다음과 같습니다.
수조에 대해 우리는 다음 표를 사용하여 처리한다.

int[] arrays = new int[10];
for(int i = 0 ; i < arrays.length ; i++){
int a = arrays[i];
//do something
}
ArrayList는 다음과 같이 처리됩니다.

List<String> list = new ArrayList<String>();
for(int i = 0 ; i < list.size() ; i++){
String string = list.get(i);
//do something
}
이 두 가지 방식에 대해 우리는 항상 집합의 내부 구조를 미리 알고 있다. 방문 코드와 집합 자체는 긴밀하게 결합되어 방문 논리를 집합 클래스와 클라이언트 코드에서 분리할 수 없다.동시에 모든 집합은 반복 방법에 대응하여 클라이언트 코드를 다시 사용할 수 없습니다.실제 응용에서 어떻게 위에서 두 집합을 통합시켜야 하는지는 상당히 번거롭다.그래서 상기 문제를 해결하기 위해 Iterator 모드가 탄생했고 항상 같은 논리로 집합을 반복했다.클라이언트 자체가 집합된 내부 구조를 유지할 필요가 없고 모든 내부 상태는 Iterator가 유지합니다.클라이언트는 집합 클래스와 직접 접촉하지 않습니다. 이것은 항상 Iterator를 제어해서'앞으로','뒤로','현재 요소를 가져오라'는 명령을 보내면 전체 집합을 간접적으로 훑어볼 수 있습니다.
위에서 Iterator 모델에 대해 간단한 설명을 했을 뿐입니다. 다음은 자바에서 Iterator 인터페이스를 보고 그가 어떻게 실현하는지 보겠습니다.
하나,java.util.Iterator
Java에서 Iterator는 하나의 인터페이스로 기본 규칙만 교체할 수 있습니다. JDK에서 그는 다음과 같이 정의합니다. 콜렉션을 교체하는 교체기입니다.교체기는 Java Collections Framework의 Enumeration을 대체합니다.교체기와 매거진은 두 가지 차이가 있다.
1. 교체기는 호출자가 정의된 좋은 의미를 이용하여 교체 기간에 교체기가 가리키는 콜렉션에서 요소를 제거할 수 있도록 한다.
2. 방법 명칭이 개선되었다.
인터페이스 정의는 다음과 같습니다.

public interface Iterator {
  boolean hasNext();
  Object next();
  void remove();
}
다음을 수행합니다.
Object next(): 교체기가 방금 넘은 요소의 인용을 되돌려줍니다. 되돌려 주는 값은 Object입니다. 필요한 형식으로 강제로 변환해야 합니다.
boolean hasNext (): 컨테이너에 액세스할 수 있는 요소가 있는지 여부를 판단합니다.
voidremove (): 교체기가 방금 넘은 요소 삭제
우리에게 있어서 우리는 일반적으로next(),hasNext() 두 가지 방법만 사용하면 교체를 완성할 수 있다.다음과 같습니다.

for(Iterator it = c.iterator(); it.hasNext(); ) {
  Object o = it.next();
   //do something
}
앞에서 Iterator의 큰 장점은 우리가 집합의 내부 결과를 알 필요가 없다는 것이다. 집합의 내부 구조, 상태는 Iterator가 유지하고 통일된 방법인hasNext(),next()를 통해 다음 요소를 판단하고 얻으면 구체적인 내부 실현에 대해 우리는 관심을 갖지 않아도 된다는 것이다.하지만 합격한 프로그래머로서 우리는 Iterator의 실현을 분명히 할 필요가 있다.다음은 ArrayList의 원본 코드를 분석 분석합니다.
2. 각 집합의 Iterator의 실현
다음은 Array List의 Iterator 실현에 대해 분석한다. 사실 우리가 Array List, Hashset, Tree Set의 데이터 구조를 이해하고 내부적으로 실현한다면 그들이 어떻게 Iterator를 실현하는지에 대해서도 대나무가 될 것이다.ArrayList의 내부 구현은 수조를 사용하기 때문에 우리는 상응하는 위치의 인덱스만 기록하면 된다. 그 방법의 실현은 비교적 간단하다.
2.1, ArrayList의 Iterator 구현
ArrayList 내부에서 먼저 내부 클래스 Itr를 정의하고 이 내부 클래스는 Iterator 인터페이스를 실현한다. 다음과 같다.

private class Itr implements Iterator<E> {
//do something
}
ArrayList의 iterator() 방법은 다음과 같습니다.

public Iterator<E> iterator() {
return new Itr();
}
그래서 Array List를 이용해서iterator () 방법은 Itr () 내부 클래스를 되돌려줍니다. 그래서 지금 우리가 관심을 가져야 할 것은 Itr () 내부 클래스의 실현입니다.
Itr 내부에 세 가지 int형 변수를 정의했습니다:cursor,lastRet,expectedModCount.그 중에서cursor는 다음 요소의 색인 위치를 나타내고lastRet는 이전 요소의 색인 위치를 나타낸다

int cursor; 
int lastRet = -1; 
int expectedModCount = modCount;
cursor,lastRet 정의를 보면 알 수 있듯이lastRet은cursor보다 적기 때문에hasNext() 실현 방법은 매우 간단하고cursor와lastRet가 같은지 아닌지만 판단하면 된다.

public boolean hasNext() {
return cursor != size;
}
next()의 실현도 비교적 간단하다. cursor 인덱스 위치의 요소를 되돌려주고 cursor,lastRet를 수정하면 된다

public E next() {
checkForComodification();
int i = cursor; // 
if (i >= size) // , 
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1; //cursor + 1
return (E) elementData[lastRet = i]; //lastRet + 1  cursor 
}
check For Comodification () 은 주로 집합의 수정 횟수가 합법적인지, 즉 반복 과정에서 집합이 수정되었는지 판단하는 데 사용된다.modCount는 ArrayList 집합의 수정 횟수를 기록하는 데 사용되며 0으로 초기화되고 집합이 수정될 때마다 (구조상의 수정, 내부 업데이트는 포함되지 않습니다.) 예를 들어add,remove 등 방법,modCount+1이기 때문에modCount가 변하지 않으면 집합 내용이 수정되지 않았음을 나타냅니다.이 메커니즘은 주로 ArrayList 집합을 실현하는 데 사용되는 빠른 실패 메커니즘이다. 자바의 집합에서 비교적 큰 부분의 집합은 빠른 실패 메커니즘이 존재한다. 여기에는 말할 것도 없고 뒤에 설명할 것이다.그러므로 반복 과정에서 오류가 발생하지 않도록 하려면 반복 과정에서 집합에 구조적인 수정이 일어나지 않도록 해야 한다. (물론remove 방법 제외) 이상 오류가 발생하면catch 이후에 처리하지 않는 것이 아니라 프로그램이 오류가 발생했는지 진지하게 검사해야 한다.

final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
remove () 방법의 실현은 ArrayList 자체의remove () 방법을 호출하여lastRet 위치 요소를 삭제하고modCount를 수정하면 됩니다.

public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
위에서 말한 것은 편집자가 여러분께 소개한 자바 집합 Iterator의 교체 실현 방법입니다. 여러분께 도움이 되었으면 합니다. 만약에 궁금한 것이 있으면 저에게 메시지를 남겨 주십시오. 편집자는 제때에 여러분에게 회답할 것입니다.여기에서도 저희 사이트에 대한 지지에 감사드립니다!

좋은 웹페이지 즐겨찾기