1️⃣ Iterable, Iterator
데이터를 차례대로 접근해서 처리하는 것
다양한 자료구조가 있고 각 자료 구조마다 데이터 접근 방법 다름.
자료구조를 동일한 방법으로 순회하기 위해 Iterable, Iterator 제공.
public interface Iterable<T> {
Iterator<T> iterator();//반복자 반환
}
public interface Iterator<E> {
boolean hasNext(); //다음 요소 존재 확인
E next(); // 다음 요소 반환
}
Iterable을 구현하면 Iterator을 반환하기 때문에 Iterable 단독 사용x
자바 컬렉션 상위에 Iterable이 있어 모든 컬렉션을 순회할 수 있도록 하였다.
각 자료구조마다 iterator을 구현하며 이를 반환한다. 따라서 각 자료구조가 Iterable 역할을 한다.
2️⃣ Comparable, Comparator
👉🏻 Comparator
public interface Comparator<T> {
int compare(T o1, T o2);
}
compare은 o1이 크면 -1, 같으면 0 , 작으면 1을 반환한다.
만약 정렬기준을 설정하고 싶을때 사용한다.
public static void main(String[] args){
Integer[] arr = {3, 2, 1};
Arrays.sort(arr,new AscComparator());//123
Arrays.sort(arr,new DescComparator());//321
}
static class AscComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
return (o1<02)?-1: ((o1 == o2) ? 0 : 1);
}
}
static class DescComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
return ((o1<02)?-1: ((o1 == o2) ? 0 : 1))*-1;
}
}
정렬을 사용할때 Arrays.sort를 사용하는데 코드를 살펴보면 Comparator을 파라미터로 입력받는 것을 확인할 수 있다.
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
👉🏻 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);
}
}
정렬 기준을 나이로 정했다. Arrays.sort(array)하면 오름차순으로 정렬되어 나타난다.
Arrays.sort(array,comparator)로 정렬방식을 지정하면 객체가 가지고 있는 Comparable(기본 정렬)을 무시하고 전달받은 기준으로 정렬한다.
트리 구조는 정렬해서 보관하기 때문에 정렬 기준을 꼭 제공해야한다.
TreeSet<MyUser> treeSet1= new TreeSet<>();//나이 기준 정렬
TreeSet<MyUser> treeSet2= new TreeSet<>(new IdComparator());//id기준 정렬
3️⃣ 컬렉션 유틸
max, min, shuffle. sort, reverse 등 다양한 기능을 제공한다.
그중, XXX.of()는 컬렉션을 편리하게 생성할 수 있지만 불변이다. List, Set, Map모두 지원한다.
public static void main(String[] args){
List<Integer> list = List.of(1, 2, 3);
ArrayList<Integer> mutableList = new ArrayList<>(list);
mutableList.add(4);
List<Integer> unmodifiableList=Collections.unmodifiableList(mutableList);
}
static class UnmodifiableList<E> extends UnmodifiableCollection<E>
implements List<E> {
@java.io.Serial
private static final long serialVersionUID = -283967356065247728L;
@SuppressWarnings("serial") // Conditionally serializable
final List<? extends E> list;
UnmodifiableList(List<? extends E> list) {
super(list);
this.list = list;
}
불변 리스트→ 가변 리스트 : new ArrayList를 사용한다.
가변 리스트→ 불변 리스트 : Collections.unmodifiableList()가 파라미터 리스트를 UnmodifiableList로 바꿔 return한다. UnmodifiableList는 final로 List가 불변이 되도록 한다.
cf) Arrays.asList() : 고정된 크기를 가지지만 요소들은 변경 가능