우리는 종종 JDK가 제공하는 반복 인터페이스를 사용하여 Java 컬렉션을 반복합니다.
iterator iterator = list.iterator (); while (iterator.hasnext ()) {문자열 string = iterator.next (); // 뭔가}} 반복은 실제로 단순히 횡단으로 이해 될 수 있습니다. 다양한 컨테이너에서 모든 객체의 트래버스를 표준화하는 방법 클래스입니다. 매우 전형적인 디자인 패턴입니다. 반복자 패턴은 수집 클래스를 통과하는 데 사용되는 표준 액세스 방법입니다. 다양한 유형의 컬렉션 클래스의 액세스 논리를 추상화하여 컬렉션의 내부 구조를 클라이언트에 노출시키는 것을 피합니다. 이것이 반복기가 없을 때 우리가 처리하는 방법입니다. 다음과 같이 :
배열의 경우 구독을 사용하여 처리합니다.
int [] arrays = new int [10]; for (int i = 0; i <arrays.length; i ++) {int a = Array [i]; // Something}} 이것이 ArrayList를 처리하는 방법입니다.
List <string> list = new ArrayList <string> (); for (int i = 0; i <list.size (); i ++) {String String = list.get (i); // 무언가를} 두 방법 모두 컬렉션의 내부 구조를 항상 미리 알고 있습니다. 액세스 코드와 컬렉션 자체는 엄격하게 결합되어 있으며 액세스 로직을 수집 클래스 및 클라이언트 코드에서 분리 할 수 없습니다. 동시에, 각 컬렉션은 트래버스 방법에 해당하며 클라이언트 코드를 재사용 할 수 없습니다. 실제 응용 분야에서 위의 두 세트를 통합하는 것은 매우 번거 롭습니다. 따라서 위의 문제를 해결하기 위해 반복자 모드는 비어 있으며 항상 동일한 논리를 사용하여 컬렉션을 통과합니다. 이로 인해 클라이언트 자체는 수집의 내부 구조를 유지할 수 없게되며 모든 내부 상태는 반복자에 의해 유지됩니다. 클라이언트는 컬렉션 클래스를 직접 처리하지 않습니다. 항상 반복기를 제어하고 "앞으로", "뒤로"및 "현재 요소를 가져 가라"명령을 보냅니다. 전체 컬렉션을 간접적으로 통과 할 수 있습니다.
위의 것은 반복자 패턴에 대한 간단한 설명 일뿐입니다. Java의 반복자 인터페이스를 살펴보고 그것을 구현하는 방법을 살펴 보겠습니다.
1. java.util.iterator
Java에서 반복적 인 기본 규칙 만 제공하는 인터페이스입니다. JDK에서는 이것으로 정의됩니다 : 수집시 반복되는 반복자. 반복자는 Java Collections 프레임 워크에서 열거를 대체합니다. 반복자와 열거 사이에는 두 가지 차이점이 있습니다.
1. 반복자를 통해 발신자는 잘 정의 된 의미를 사용하여 반복하는 동안 반복자가 가리키는 컬렉션에서 요소를 제거 할 수 있습니다.
2. 메소드 이름이 개선되었습니다.
인터페이스 정의는 다음과 같습니다.
공개 인터페이스 반복자 {boolean hasnext (); 객체 다음 (); void remove ();} 안에:
Object Next () : 반복자가 교차하는 요소에 대한 참조를 반환합니다. 리턴 값은 객체이며 필요한 유형으로 캐스트해야합니다.
Boolean hasnext () : 컨테이너에 액세스 할 수있는 요소가 있는지 결정합니다.
void remove () : 반복자가 방금 교차 한 요소를 제거합니다.
우리는 반복을 완료하기 위해 다음 () 및 hasnext () 만 사용하면됩니다. 다음과 같이 :
for (iterator it = c.ertator (); it.hasnext ();) {object o = it.next (); // 뭔가} 이전의 설명은 반복자가 큰 이점, 즉 세트의 내부 결과를 알 필요가 없다는 것입니다. 세트의 내부 구조 및 상태는 반복자에 의해 유지됩니다. 통합 된 메소드 hasnext () 및 다음 ()을 통해 다음 요소를 판단하고 얻습니다. 특정 내부 구현에 관해서는 걱정할 필요가 없습니다. 그러나 자격을 갖춘 프로그래머로서 반복자의 구현을 파악해야합니다. ArrayList의 소스 코드는 아래에 분석됩니다.
2. 각 컬렉션에 대한 반복자 구현
ArrayList의 반복자 구현을 분석하겠습니다. 실제로 ArrayList, HashSet 및 TreeSet의 데이터 구조를 이해하고 내부적으로 구현하면 반복자를 구현하는 방법에 대해 확신합니다. ArrayList의 내부 구현은 배열을 사용하므로 해당 위치의 인덱스 만 기록하면됩니다. 메소드 구현은 비교적 간단합니다.
2.1. ArrayList의 반복자 구현
내부 ArrayList는 먼저 반복자 인터페이스를 구현하는 내부 클래스 ITR을 정의합니다.
개인 클래스 ITR은 반복자 <e> {// do do something}을 구현합니다. ArrayList의 iterator () 메소드가 구현됩니다.
public iterator <e> iterator () {return new itr ();} 따라서 ArrayList.iterator ()의 방법은 ITR () 내부 클래스를 반환하므로 지금 우리가 관심을 가져야 할 것은 ITR () 내부 클래스의 구현입니다.
ITR 내부에는 3 개의 int- 타입 변수가 정의되어 있습니다 : 커서, lastret 및 expostModCount. 여기서 커서는 다음 요소의 인덱스 위치를 나타내고 Lastret은 이전 요소의 인덱스 위치를 나타냅니다.
int 커서; int lastret = -1; int exclingModCount = modCount;
Cursor와 Lastret의 정의에서 Lastret은 항상 Cursor보다 하나가 적었으므로 Hasnext ()의 구현 방법은 매우 간단합니다. Cursor와 Lastret이 동일한지 판단하면됩니다.
public boolean hasnext () {return cursor! = size;} 다음 ()의 구현은 실제로 비교적 간단합니다. 커서 인덱스 위치에서 요소를 반환 한 다음 커서와 라스 트릿을 수정하십시오.
public e next () {checkforcomodification (); int i = 커서; // (i> = size) 인 If (i> = size) // 획득 요소가 수집 요소의 수보다 큰 경우, 예외는 새로운 nosuchelementException (); object [] elementData = arrayList.this.elementData; if (i> = ElementData.length) Throw New ConcurrentModificationException (); cursor = i + 1; // cursor + 1return (e) ElementData [lastret = i]; // lastret + 1과 Cursor에서 요소를 반환} CheckforComodification ()은 주로 세트 수정 수가 합법적인지, 즉 트래버스 프로세스 중에 세트가 수정되었는지 여부를 결정하는 데 주로 사용됩니다. ModCount는 ArrayList Collection의 수정 수를 기록하고 0으로 초기화하고 컬렉션을 한 번 수정할 때마다 (내부 업데이트가 구조에 대해서는 계산되지 않음) ADD, 제거 및 기타 방법과 같은 MODCOUNT + 1, MODCOUNT가 변경되지 않은 경우 컬렉션의 내용이 수정되지 않았 음을 의미합니다. 이 메커니즘은 주로 Arraylist Collection의 빠른 고장 메커니즘을 구현하는 데 사용됩니다. Java 컬렉션에서는 컬렉션의 대부분이 빠른 고장 메커니즘을 가지고 있습니다. 나는 여기서 그것에 대해 이야기하지 않을 것이고 나중에 그것에 대해 이야기 할 것입니다. 따라서 트래버스 프로세스 중에 오류가 없도록하려면 트래버스 프로세스 중 수집에 대한 구조적 수정이 없도록해야합니다 (제거 방법 제외). 예외 오류가 발생하면 프로그램에 캐치 후 처리하지 않고 오류가 있는지주의 깊게 확인해야합니다.
최종 void checkforcomodification () {if (modCount! = exclingModCount) 새 동시 동의 modificationException ()를 던지십시오. remove () 메소드는 Lastret 위치 요소를 삭제 한 다음 ModCount를 수정하기 위해 ArrayList 자체의 remove () 메소드를 호출하는 구현입니다.
public void remove () {if (lastret <0) 던지기 새로운 불법 스테이트 exception (); checkforcomodification (); checkforcomodification (); try {arraylist.tris.remove (lastret); cursor = lastret; lastret = -1; exclingModCount = modcount;} catch (indexoutOfBoundSection ex);위는 편집자가 귀하에게 소개 한 Java Collection Iterator Iteration의 구현 방법입니다. 나는 그것이 당신에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!