하지만 다양한 자료 구조로 각각의 자료 구조마다 데이터를 접근하는 방식은 모두 다른르다.
자바는 자료 구조의 구현과 관계없이 모든 자료 구조를 동일한 방법으로 순회할 수 있는 Iterable
과 Iterator
인터페이스를 제공한다
Iterator
인터페이스의 주요 메서드
hasNext():
다음 요소가 있는지 확인한다. 다음 요소가 없으면 fasle
를 반환한다.next():
다음 요소를 반환한다. 내부에 있는 위치를 다음으로 이동시킨다.Iterator
구현체
package collection.iterable;
import java.util.Iterator;
public class MyArrayIterator implements Iterator<Integer> {
private int currentIndex = -1;
private int[] targetArr;
public MyArrayIterator(int[] targetArr) {
this.targetArr = targetArr;
}
@Override
public boolean hasNext() {
return currentIndex < targetArr.length - 1;
}
@Override
public Integer next() {
return targetArr[++currentIndex];
}
}
int
배열을 참조한다.currentIndex:
현재 인덱스, next()
를 호출할 때마다 1씩 증가한다.hasNext():
다음 항목이 있는지 검사한다. 배열의 끝에 다다르면 순회가 끝났으므로 false
를 반환한다.next():
다음 항목을 반환한다.자바는 iterable
인터페이스를 구현한 객체에 대해서 향상된 for문을 사용할 수 있게 해준다.
for (int value : myArray) {
System.out.println("value = " + value);
}
while (iterator.hasNext()) {
Integer value = iterator.next();
System.out.println("value = " + value);
}
자바는 컴파일 시점에 향상된 for문을 아래의 코드로 변경해서 돌린다.
Iterable
인터페이스를 제공하고, 각각의 구현체에 맞는 Iterator
도 다 구현했다.Collection
인터페이스의 상위에 Iterable
이 있다는 것은 모든 컬렉션을 Iterable
과Iterator
를 사용해서 순회할 수 있다는 뜻이다.Map
의 경우 Key
뿐만 아니라 Value
까지 있기 때문에 바로 순회할 수는 없다. 대신에 Key
나 Value
를 정해서 순회할 수 있다. KeySet()
,Values()
를 호출하면 Set
,Collection
을 반환하기 때문에 Key
나 Value
를 정해서 순회할 수 있다.비교자 Comparator
는 두 값을 비교할 때 비교 기준을 직접 제공해준다.
public interface Comparator<T> {
int compare(T o1, T o2);
}
static class AscComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println("o1=" + o1 + " o2=" + o2);
return (o1 < o2) ? -1 : ((o1 == o2) ? 0 : 1);
}
}
static class DescComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println("o1=" + o1 + " o2=" + o2);
return ((o1 < o2) ? -1 : ((o1 == o2) ? 0 : 1)) * -1;
}
}
AscComparator
를 사용하면 숫자가 점점 올라가는 오름차순으로 정렬된다.DescComparator
를 사용하면 숫자가 내림차순으로 정렬된다. Arrays.sort(array, new AscComparator())
Arrays.sort(array, new DescComparator())
정렬을 반대로 하고 싶으면 reversed()
메서드를 사용하면 된다. 이 메서드를 사용하면 비교의 결과를 반대로 변경한다.
new AscComparator().reversed()
자바가 기본적으로 제공하는 객체를 제외하고 사용자가 직접 만든 객체를 정렬하려면 Comparable
인터페이스를 구현하면된다. 이 인터페이스는 이름 그대로 객체에 비교 기능을 추가해 준다.
public class MyUser implements Comparable<MyUser> {
private String id;
private int age;
public MyUser(String id, int age) {
this.id = id;
this.age = age;
}
public String getId() {
return id;
}
public int getAge() {
return age;
}
@Override
public int compareTo(MyUser o) {
return this.age < o.age ? -1 : (this.age == o.age ? 0 : 1);
}
@Override
public String toString() {
return "MyUser{" +
"id='" + id + '\'' +
}
}
MyUser
가 Comparable
인터페이스를 구현함compareTo()
에서 정렬의 기준을 age
로 지정MyUser
클래스의 기본 정렬 방식을 나이 오름차순으로 한 것이다. @Override
public int compare(MyUser o1, MyUser o2) {
return o1.getId().compareTo(o2.getId());
}
Collections.sort(list)
list.sort(null)
Comparable
로 비교해서 정렬한다.Collections.sort(list, new IdComparator())
list.sort(new IdComparator())