반응형
처음으로 살펴볼 소스코드는 Iterator.
주로 List, Set등 Collection 프레임 워크에서 특정 객체를 삭제하고 싶을 때 사용했었다.
자바 1.8부터 지원하는 removeif라는 method를 통해서 쉽게 없앨 수 있는데... 있는줄도 모르고 Iterator를 사용했었다.
쨋든 Iterator ㄱ.ㄱ
public interface Iterator<E> {
boolean hasNext(); //원소가 더 있으면 true
E next(); // 다음 원소 return, 원소가 더 없으면 NoSuchElementException 리턴
/**
* The behavior of an iterator is unspecified if the underlying collection
* is modified while the iteration is in progress in any way other than by
* calling this method, unless an overriding class has specified a
* concurrent modification policy.
* <p>
*/
// next이후에 한번씩만 remove를 call할 수 있음.
// 마지막 next로부터 call한 객체를 제거한다.
// forEachRemaining이후에 call한 경우에 대해서는 따로 정의 안돼있음.
// next를 호출하지 않고 remove한 경우 or 이미 remove를 호출한 경우
// IllegalStateException발생.
// Iterator를 implement하지 않는 경우 기본적으로 UnsupportedOperationException발생
default void remove() {
throw new UnsupportedOperationException("remove");
}
// 남은걸로 forEach돌리는것이다.
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
메서드가 4개밖에 없어서.. 좋다. ㅋㅋ
메서드 | 설명 |
E next(); | 다음 원소를 return. |
boolean hasNext(); | 다음 원소가 있는 경우 true |
default void remove() | next() 불린이후 호출해야하며 next로 불린 값을 제거한다. 그렇지 않은 경우, 예외를 던진다. |
default forEachRemaining(Consumer<? super E> action) | 남은 원소에 대해 forEach를 실행한다. |
사용 예시 - List
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
Iterator<Integer> iterator = list.iterator(); // 0,1,2,3,4,5,6,7,8,9
while (iterator.hasNext()) {
int i = iterator.next(); // 3이 할당됨.
if (i % 3 == 0) {
iterator.remove(); // 3의 배수인 경우 삭제
}
}
// forEach
list.forEach(System.out::println); // 1,2,4,5,7,8출력됨
// forEachRemaining -> 이미 다 소모되서 프린트 안됨.
iterator.forEachRemaining(System.out::println);
// iterator 다시 불러옴.
iterator = list.iterator();
iterator.forEachRemaining(System.out::println);
}
ArrayList에서 어떤식으로 Iterator가 구현되었을까?
ArrayList에서 Iterator
.iterator()를 호출하면 new Iter()로 Iterator를 리턴한다.
동시 수정을 확인하는 method도 보이고, Iterator interface를 구현한 부분도 확인할 수 있다.
private class Itr implements Iterator<E> {
int cursor; // next를 가리키는 커서
int lastRet = -1; // 리턴된 마지막 원소의 index
int expectedModCount = modCount; // 동시 수정을 막기위함.(해당 내용은 ArrayList에서 자세히...)
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
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;
return (E) elementData[lastRet = i];
}
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();
}
}
@Override
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int size = ArrayList.this.size;
int i = cursor;
if (i < size) {
final Object[] es = elementData;
if (i >= es.length)
throw new ConcurrentModificationException();
for (; i < size && modCount == expectedModCount; i++)
action.accept(elementAt(es, i));
// update once at end to reduce heap write traffic
cursor = i; // 끝나면 i = size
lastRet = i - 1; // last returned index를 갖고 있음.
checkForComodification();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
반응형
'Java' 카테고리의 다른 글
[Java] 소스코드 탐험 - 2. ArrayList(feat. AbstractList) (0) | 2023.07.23 |
---|---|
[Java] List정렬(sort)/ Collections.sort, List.sort (0) | 2023.02.11 |
[Java] 스트림 - Stream : 효율적인 데이터 다루기! (0) | 2022.09.18 |
[Java] Optional<T>, Optional 타입 : 래퍼 클래스, 코드의 복잡성을 낮추다. (0) | 2022.09.04 |
[Java] Wrapper 클래스 : 기본 타입의 데이터를 객체로 취급하다.( 오토박싱, 오토언박싱) (0) | 2022.09.03 |
댓글