자바의 컬렉션 프레임워크가 컬렉션에 저장된 요소를 읽어오는 방법 표준화 한 인터페이스
Collection 인터페이스에서는 Iterator 인터페이스를 구현한 클래스의 인스턴스를 반환하는 iterator() 메소드를 정의하여 각 요소에 접근하도록 하기 때문에 Collection 인터페이스를 상속받는 List와 Set 인터페이스에서도 iterator() 메소드를 사용할 수 있다
LinkedList<Integer> lnkList = new LinkedList<Integer>();
lnkList.add(4);
lnkList.add(2);
lnkList.add(3);
lnkList.add(1);
Iterator<Integer> iter = lnkList.iterator();
while (iter.hasNext()) {
System.out.print(iter.next() + " ");
}
현재 자바에서는 JDK 1.5 버전 이후부터 추가된 Enhanced for문을 사용하도록 권장
하지만 Enhanced for문은 읽기 전용 권한만 제공하기 때문에 요소를 선택적으로 제거하거나 대체를 하기 위해서는 반복자를 사용해야 한다
ListIterator 인터페이스
Iterator 인터페이스가 컬렉션의 요소에 접근할 떄 한 방향으로만 이동할 수 있다는 단점을 보완하기 위하여 Iterator 인터페이스를 상속받아 여러 기능을 추가한 인터페이스
ListIterator 인터페이스는 컬렉션 요소의 대체, 추가 그리고 인덱스 검색 등을 위한 작업에서 양방향으로 이동하는 것을 지원한다
List 인터페이스를 구현한 List 컬렉션 클래스에서만 listIterator() 메소드를 통해 사용할 수 있다
LinkedList<Integer> lnkList = new LinkedList<Integer>();
lnkList.add(4);
lnkList.add(2);
lnkList.add(3);
lnkList.add(1);
ListIterator<Integer> iter = lnkList.listIterator();
while (iter.hasNext()) {
System.out.print(iter.next() + " ");
}
while (iter.hasPrevious()) {
System.out.print(iter.previous() + " ");
}
4 2 3 1
1 3 2 4
Comparable 인터페이스
Comparable 인터페이스에서 객체를 비교하고 이를 통해 정렬할 때 사용되는 메소드인 compareTo() 메소드
자바에서 같은 타입의 인스턴스를 서로 비교해야만 하는 클래스들은 모두 Comparable 인터페이스를 구현하고 있기 때문에 Boolean을 제외한 래퍼 클래스나 String, Time, Date와 같은 클래스의 인스턴스는 모두 정렬 가능하다
만일 사용자 정의 클래스의 인스턴스를 비교할 때는 아래와 같이 CompareTo를 overide 해줘야 한다
class Car implements Comparable<Car> {
private String modelName;
private int modelYear;
private String color;
Car(String mn, int my, String c) {
this.modelName = mn;
this.modelYear = my;
this.color = c;
}
public String getModel() {
return this.modelYear + "식 " + this.modelName + " " + this.color;
}
public int compareTo(Car obj) {
if (this.modelYear == obj.modelYear) {
return 0;
} else if(this.modelYear < obj.modelYear) {
return -1;
} else {
return 1;
}
}
}
public class Comparable01 {
public static void main(String[] args) {
Car car01 = new Car("아반떼", 2016, "노란색");
Car car02 = new Car("소나타", 2010, "흰색");
System.out.println(car01.compareTo(car02));
}
}
1
compareTo() 메소드는 두 객체간의 상대적인 순서를 반환한다
Integer a = 3;
Integer b = 5;
int result = a.compareTo(b);
-1
그러면 equals를 안쓰고 compareTo()를 쓰는 이유는 뭘까?
equals는 두 인스턴스의 값이 같은지 다른지를 boolean 값을 통해서 알려주는 것이고, compareTo() 메소드는 두 값의 상대적인 순서를 반환하여 객체들간의 순서나 정렬이 가능하도록 해준다
Comparator 인터페이스
Comparable 인터페이스를 구현한 클래스는 오름차순 정렬되는 것에 반해 내림차순이나 아니면 다른 기준으로 정렬하고 싶을 때 사용하는 인터페이스
이때 Comparator 인터페이스를 구현한 클래스에서 compare() 메소드를 재정의하여 사용함
import java.util.*;
class DescendingOrder implements Comparator<Integer> {
public int compare(Integer o1, Integer o2) {
if(o1 instanceof Comparable && o2 instanceof Comparable) {
Integer c1 = (Integer)o1;
Integer c2 = (Integer)o2;
return c2.compareTo(c1);
}
return -1;
}
}
public class Comparable02 {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<Integer>(new DescendingOrder());
ts.add(30);
ts.add(40);
ts.add(20);
ts.add(10);
Iterator<Integer> iter = ts.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
}
}
40
30
20
10
TreeSet은 자료를 정렬된 순서로 유지하는 Set의 구현체이기 때문에 새로운 요소를 추가하거나 기존 요소와 비교할 필요가 있을 때 compare() 메소드 또는 compareTo() 메소드를 내부적으로 호출한다
위의 코드와 같이 Comparator 객체가 주어지면 compare() 메소드를 호출하고 아무것도 안주어지면 기본적으로 compareTo() 메소드를 호출한다
(하지만 이때는 해당 객체가 Comparable 인터페이스를 구현해야만 compareTo()를 호출함)