알고리즘 문제를 풀던 중, 한 가지 의문을 해결한 것에 대해 적어 놓으려고 한다.
map이라는 클래스를 하나 정의하고 ArrayList<map> 타입의 객체를 생성해서
사용하던 중 Collections.sort()를 사용하려고 했다.
Collections.sort()
제네릭 타입에는 map 객체를 넣었는데, 위와 같이 에러가 발생하였다.
Integer나 String 등을 넣으면 괜찮은데 왜이럴까?
당연히 String클래스에 equals()를 오버라이딩 한 것과 같은 이유이다.
Integer등의 클래스에는 이미 sort()를 사용할 수 있게끔 조건을 만족 시켜 놓았다.
그렇다면 어떤 조건이 있어야 사용이 가능할까? 알아보기 위해서 Collections클래스의 sort()메소드를 살펴 보았다.
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(c);
}
위 코드는 Collections 클래스 내부에 구현되어 있는 sort() 메소드이다.
우선, <T extends Comparable>라고 타입변수가 선언되어 있는 것을 확인할 수 있었다.
즉, 타입변수 T는 Comparable 인터페이스를 구현한 타입이여야 하는 것이다.
또한 타입변수 T가 매개변수 list의 제네릭 타입으로 사용되고 있는 것을 확인할 수 있다.
참고로 Comparable인터페이스의 compareTo()를 구현할 때는
음수면 오른쪽, 양수면 왼쪽, 0이면 동일하다고 오버라이딩 해줘야한다.
따라서 어떤 값에서 어떤 값을 빼느냐에 따라 해당 배열이 오름차순이 될 수도, 내림차순이 될 수도 있는 것이다.
Arrays.sort()
구현된 부분을 살펴보면 list.sort()인데, 해당 sort()를 따라가보면 아래와 같이 되어있다.
Arrays.sort(a, (Comparator) c);
즉, Arrays.sort(a, c)가 있는 것을 보아 지정한 Comparator에 의해서 정렬됨을 확인할 수 있다.
위와 같은 이유로 Collections에 구현된 sort()메소드를 사용하기 위해서는 Comparable 인터페이스에 있는 정렬기준(compareTo())을 구현해야 하는 것이다.
만약 컬렉션을 사용하지 않고 배열을 선언했다면?
ArrayList<map> m2 = new ArrayList<>();
Collections.sort(m2);
만약 map클래스가 Comparable 인터페이스를 구현하지 않았다면, 컴파일 에러가 발생할 것이다.
그 이유는 위에 설명한 것과 마찬가지로 Collections의 sort는 Comparable을 구현해야하는 타입변수가 선언되어 있기 때문이다.
(Collections.sort()를 타고 들어가면 Arrays.sort(a, (Comparator) c)을 사용하고 있음.)
그렇다면 아래와 같은 배열이라면?
map[] m = new map[2];
m[0] = new map(0,1);
m[1] = new map(0,1);
Arrays.sort(m);
위와 같이 객체 배열에서 Arrays.sort()를 사용하고 Comparator를 지정해주지 않는다면 컴파일 에러는 발생하지 않는다.
하지만 런타임에러가 발생하게 되어있다.
그 이유는 Arrays.sort(a)에서 이와 같이 Comparator를 지정해주지 않는다면 객체배열에 저장된 객체가 구현한 Comparable에 의해서 정렬되는데 현재 map 객체에서는 구현되어 있지 않기 때문이다.
'JAVA' 카테고리의 다른 글
JVM의 동작 원리와 구조 구체적으로 이해하기 (3) | 2024.02.12 |
---|---|
3. 예외와 예외처리 (0) | 2022.12.15 |
1. 자바 컴파일 과정 (0) | 2022.11.23 |
22. 인터페이스 (0) | 2022.11.14 |
21. 추상 클래스, 추상 메서드 (0) | 2022.11.11 |