Array List 의 modcount 에 대해 이야기 합 니 다.
교체 기 Iterator 는 낯 설 지 않 을 것 입 니 다.Array List,LinkedList,HashSet 등 여러 가지 바 텀 에 서로 다른 용 기 를 실현 합 니 다.예 를 들 어 Array List 바 텀 은 하나의 배열 입 니 다.LinkedList 는 링크 구조 이 고 HashSet 은 해시 표 에 의존 합 니 다.모든 용기 에 자신 만 의 독특한 데이터 구조 가 있 는 상황 에서 고객 이 이런 집합 중의 요 소 를 옮 겨 다 녀 야 한다 면그들 이 어떻게 실현 되 었 는 지 알 필요 가 없다.
이 용기 들 은 모두 교체 기 에 대한 실현 이 있다.ArrayList 가 져 오기 예 를 들 어 Array List 에 iterator()방법 이 있 음 을 알 수 있 습 니 다.
public Iterator iterator() {
return new Itr();
}
방법 은 Itr 대상 을 되 돌려 줍 니 다.Itr 는 Array List 의 내부 클래스 입 니 다.코드 는 다음 과 같 습 니 다.
private class Itr implements Iterator {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor < limit;
}
@SuppressWarnings("unchecked")
public E next() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
int i = cursor;
if (i >= limit)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
limit--;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
이 modCount 는 이 교체 기 대상 이 수 정 된 횟수 를 대표 합 니 다.교체 기 대상 마다 수 정 됩 니 다.modCount 는 1.remove 방법 에 이 문구 가 있 습 니 다. expectedModCount = modCount;
Itr 클래스 에 구성원 변수 expected ModCount 가 있 습 니 다.이 값 은 Itr 대상 을 만 들 때 List 의 modCount 값 입 니 다.이 변 수 를 사용 하여 교체 과정 에서 List 대상 이 수정 되 었 는 지 확인 하고 수정 되면 자바 util.Concurrent ModificationException 이상 을 던 집 니 다.Itr 대상 의 next()방법 을 호출 할 때마다 checkForComodification()방법 을 사용 하여 검 사 를 합 니 다.checkForComodification()방법 에서 하 는 일 은 expected ModCount 와 modCount 의 값 이 같 는 지 비교 하 는 것 입 니 다.같 지 않 으 면 다른 대상 이 현재 List 를 조작 하고 있다 고 생각 합 니 다.그 건 Concurrent ModificationException 이상 을 던 집 니 다.예 를 들 어:
public static void main(String[] args) {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String str = (String) iterator.next();
if (str.equals("c")) {
list.remove(str);
} else {
System.out.println(str);
}
}
}
결국
a
b
Exception in thread "main" java.util.ConcurrentModificationException
메모:remove 방법 은 iterator 가 아 닌 list 대상 을 호출 합 니 다.list 의 remove 방법 에는 없습니다. expectedModCount=modCount 문장!
ArrayList 의 remove 방법:
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
즉,list.remove(str)가 실 행 된 후 modCount++는 할당 되 지 않 았 습 니 다. expected ModCount,그래서 지금 expected ModCount 는 modCount 와 같 지 않 기 때문에 다음 next()방법 에 있 는 checkForComodification()은 이상 을 던 집 니 다.
list.remove(str)를 iterator.remove()로 바 꾸 면 정상적으로 실 행 됩 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.