주로 List나 Set과 같은 컬렉션에서 자료 구조의 내부요소들을 순차적으로 처리하고 읽어오기 위해 필요한 인터페이스다.
for문으로도 순차적 접근이 가능한데, 왜 추가적으로 iterator가 필요할까?
예컨대 set같은 경우는 순서가 없는 컬렉션이므로 인덱스 또한 없다. 따라서 일반 for문을 사용할 수 없고 for-each문을 사용할 수 있다. 그러나 값을 수정,삭제하는 코드를 넣으면 ConcurrentModificationException이 발생한다.
하지만 iterator는 예외 발생 없이 반복하는 동안 요소 제거를 할 수 있다. 이외에도 iterator가 갖는 장점으로는,
1. next() previous()를 써써 앞뒤로 이동하는 기능
2. hasNext()를 써서 더 많은 요소가 있는지 확인하는 기능이 있다.
ArrayList를 만들고 값을 넣은 후, 이 리스트에 대해 iterator를 만든 다음 반복문을 통해 값을 출력하는 예제.
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
// 컬렉션 생성
ArrayList<String> cars = new ArrayList<>();
cars.add("벤츠");
cars.add("람보르기니");
cars.add("롤스로이스");
cars.add("페라리");
// iterator 획득
Iterator<String> iterator = cars.iterator();
// while문을 사용한 경우
while(iterator.hasNext()) {
String str = iterator.next();
System.out.println(str);
}
// for-each문을 사용한 경우
for (String str : cars) {
System.out.println(str);
}
}
}
// >> 벤츠
// >> 람보르기니
// >> 롤스로이스
// >> 페라리
Set을 사용하는 경우에는 출력시 넣은 순서와 상관 없이 값이 출력된다.
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<String> cars = new HashSet<>();
cars.add("벤츠");
cars.add("람보르기니");
cars.add("롤스로이스");
cars.add("페라리");
// while문을 사용한 경우
Iterator<String> iterator = cars.iterator();
while(iterator.hasNext()) {
System.out.println("cars : " + iterator.next());
}
// for-each문을 사용한 경우
for (String car : cars) {
System.out.println("cars : " + car);
}
}
}
// >> cars : 람보르기니
// >> cars : 롤스로이스
// >> cars : 페라리
// >> cars : 벤츠
iterator를 사용해 값을 수정하는 예제
import java.util.ArrayList;
import java.util.ListIterator;
public class Main {
public static void main(String[] args) {
// 컬렉션 생성
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
list.add("F");
System.out.println("while문 지나기 전 리스트에 들어있던 값 : " + list);
// 리스트에 들어있는 값에 각각 '+' 붙이기
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()) {
Object element = listIterator.next();
listIterator.set(element + "+");
}
System.out.println("while문 지난 후 수정된 결과 : " + list);
// 리스트에 들어있는 값을 역순으로 표시
System.out.print("역순 출력 결과 : ");
while(listIterator.hasPrevious()) {
Object element = listIterator.previous();
System.out.print(element + " ");
}
System.out.println();
}
}
// >> while문 지나기 전 리스트에 들어있던 값 : [A, B, C, D, E, F]
// >> while문 지난 후 수정된 결과 : [A+, B+, C+, D+, E+, F+]
// >> 역순 출력 결과 : F+ E+ D+ C+ B+ A+
경고를 제외시킬 때 사용하는 어노테이션이다. IDE에서는 오류까지는 아니지만 사용상 적절하지 않은 부분에 노랗게 경고를 준다. 이 어노테이션을 쓰면 그러한 경고를 무시한다.
@SuppressWarnings("rawtypes")=> 하나만 적용할 경우
@SuppressWarnings({"rawtypes", "unchecked"})=> 두개 이상 적용할 경우
all : 모든 경고
cast : 캐스트 연산자 관련 경고
dep-ann : 사용하지 말아야 할 주석 관련 경고
deprecation : 사용하지 말아야 할 메서드 관련 경고
fallthrough : switch문에서 break 누락 관련 경고
finally : 반환하지 않는 finally 블럭 관련 경고
null : null 분석 관련 경고
rawtypes : 제너릭을 사용하는 클래스 매개 변수가 불특정일 때의 경고
unchecked : 검증되지 않은 연산자 관련 경고
unused : 사용하지 않는 코드 관련 경고
import java.util.*;
public class JavaIterator{
static Iterator func(ArrayList mylist){ // mylist: size = 5 {42 10 ### hello java}
Iterator it=mylist.iterator();
while(it.hasNext()){ //hasNext()는 boolean 타입의 반환, next()는 매개변수 혹은 iterator 되는 타입으로 반환
Object element = it.next();
if(element instanceof String)//element가 String이거나 String을 상속받는 클래스면 true를 반환한다. 아니면 false 반환.
break; // ###이 입력되면 break 하고 it으로 리턴
}
return it;
}
@SuppressWarnings({ "unchecked" }) //경고를 제외시킬 때 쓰는 어노테이션
public static void main(String []args){
ArrayList mylist = new ArrayList();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
for(int i = 0;i<n;i++){
mylist.add(sc.nextInt());
}
mylist.add("###");
for(int i=0;i<m;i++){
mylist.add(sc.next());
}
Iterator it=func(mylist);
while(it.hasNext()){
Object element = it.next(); // element: hello java
System.out.println((String)element); // print: hello java
}
}
}