정렬 Comparator<'T'> 기반
- 들어가기 앞서 <? extends T>, <? super T>에 대해서 복습해보자.
<? extends T> -- 상한 제한 T이거나 T를 상속하는 클래스들만 가능하다.
(T이거나 T의 자식 클래스들) (꺼내는 것 Get만 가능)
<? super T> -- 하한 제한 T이거나 T가 상속하는 클래스들만 가능하다.
(T이거나 T의 부모 클래스들) (넣는것 Set만 가능)
Collections 클래스에는 다음 sort 메소드도 정의되어 있다.
이는 호출시 정렬의 기준을 결정할 수 있는 형태로 정의된 메소드이다.
public static <T> void sort(List<T> list, Comparator<? super T> c)
그리고 이번에는 매개변수 선언에 <? super T>가 있으므로 다음과 같이 판단할 수 있다.
" 매개변수 c를 대상으로는 T형 인스턴스를 넣는(전달하는(Set)) 메소드 호출만 OK.
예제를 통해서 <? super T> 선언이 주는 두번째 의미를 확인해보자.
class Car{
protected int disp;
public Car(int d){disp = d;}
@Override
public String toString(){return "cc: " +disp;}
}
class Carcomp implements Comparator<Car> {
@Override
public int compare(Car o1, Car o2){return o1.disp - o2.disp;}
}
class Ecar extends Car{
private int battery;
public Ecar(int d, int b){
super(d);
battery = b;
}
@Override
public String toString(){return "cc: " + disp +" ba : " +battery;}
}
public class CarComparator {
public static void main(String[] args) {
List<Car> clist = new ArrayList<>();
clist.add(new Car(1800));
clist.add(new Car(1200));
clist.add(new Car(3000));
List<Ecar> elist = new ArrayList<>();
elist.add(new Ecar(3000,55));
elist.add(new Ecar(1800,87));
elist.add(new Ecar(1200,99));
Carcomp comp = new Carcomp();
Collections.sort(clist,comp);
Collections.sort(elist,comp);
for(Iterator<Car3> itr = clist.iterator(); itr.hasNext();)
System.out.println(itr.next().toString() + '\t');
System.out.println();
for(Iterator<Ecar3> itr = elist.iterator(); itr.hasNext();)
System.out.println(itr.next().toString() + '\t');
}
}
---------------------------------------------------------------------
cc: 1200
cc: 1800
cc: 3000
cc: 1200 ba : 99
cc: 1800 ba : 87
cc: 3000 ba : 55
이는 sort 메소드의 두번째 매개변수 타입이 Comparator<T>가 아닌
Comparator<? super T>이기에 가능한 일이다.
찾기 binarySearch
리스트 자료구조를 기반으로 특정 인스턴스를 찾을때 사용할수 있는 메소드가
Collections 클래스에 다음과 같이 정의되어 있다.
public static
<T> int binarySearch(List<? extends Comparable<? superT>> list, T key)
-> list에서 key를 찾아 그 인덱스 값 반환 못찾으면 음의 정수 반환
풀어서 읽어보자
public static <T> int binarySearch(List<?> list, T key)
"첫 번째 인자로 List<E> 인스턴스는 무엇이든 올 수 있다.
public static
<T> int binarySearch(List<? extends Comparable<? superT>> list, T key)
"첫 번째 인자로 List<E> 인스턴스는 무엇이든 올 수 있다."
"단 이때 E는 Comparable<T>를 구현해야 한다."
---------------------------------------------------------------------
예제를 통해 확인해보자
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Box");
list.add("Robot");
list.add("Apple");
Collections.sort(list);
int idx = Collections.binarySearch(list, "Robot");
System.out.println(list.get(idx));
---------------------------------------------------------------------
Robot
찾기 : Comparator<'T'> 기반
public static <T>
int binarySearch(List<? extends T>list,T key,Comparator<?superT> c
-> list에서 key를 찾는데 c의 기준을 적용하여 찾는다.
이 메소드도 한눈에 들어오지 않는다면 다음과 같이 줄여놓고 이해하자.
public static<T>
int binarySearch(List<T> list, T key, Comparator<T> c)
그리고 나서 <? extends T>와 <? super T>의 의미를 덧붙이자.
- List<T> 아니고 List<? extends T>인 이유는 list에서 T형 인스턴스를
꺼내는 것만(Get) 허용하기 위해.
- Comparator<T>아니고 Comparator<? super T>인 이유는 Ecar 클래스를 통해 설명한것.
예제 ---------------------------------------------------------------------
class StrComp implements Comparator<String> {
@Override
public int compare(String s1, String s2){
return s1.compareToIgnoreCase(s2);
}
}
public class StringComparator {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("ROBOT");
list.add("APPLE");
list.add("BOX");
StrComp cmp = new StrComp();
Collections.sort(list, cmp);
int idx = Collections.binarySearch(list,"Robot",cmp);
System.out.println(list.get(idx));
}
}
----------------------------------------------------------------------
ROBOT
public int compareToIgnoreCase(String str)
-> 두 문자열이 같을때 0을 반환(대소문자 구분 없이함)
복사하기 copy
public static<T> void copy(List<? super T> dest,List <? extends T> src)
-> src의 내용을 dest로 복사
List<T> dest 아닌 List<? super T> dest인 이유는?
-> dest에 T형 인스턴스를 넣는 것만(Set) 허용하겠다. 꺼내면(Get) 컴파일 에러!
List<T> src 아닌 List<? extends T> src 인 이유는?
-> src로부터 T형 인스턴스 꺼내는 것만(Get) 허용하겠다. 넣으면(Set) 컴파일 에러!
예제-----------------------------------------------------------------
List<String> src = Arrays.asList("Box", "Apple", "Toy", "Robot");
List<String> dest = new ArrayList<>(src);
Collections.sort(dest);
System.out.println(dest);
Collections.copy(dest,src);
System.out.println(dest);
---------------------------------------------------------------------
[Apple, Box, Robot, Toy]
[Box, Apple, Toy, Robot]
컬렉션 인스턴스를 생성하지 않은 상태에서 복사본을 만들려면 다음 방법을 사용하면 된다.
List<String> dest = new ArrayList<>(src);