본문 바로가기

dev/languages

[Java] ArrayList 정렬하기 - Comparable, Comparator 인터페이스의 차이와 Collection.sort() 사용

반응형

 

 

 

 

아직 자바에 대한 깊은 이해가 없는 상태에서

너무너무너무! 어려운 부분이었기 때문에

저 같은 분들을 위해 최대한 '직관적'으로 설명해 보겠습니다..

 

 

 

 

 

참고 - 일반 배열의 정렬

 

import java.util.Arrays;

Arrays.sort(배열명);

java.util.Arrays의 sort() 메소드 사용

문자열 배열일 경우 앞글자부터 체크하며 문자의 코드가 누가 더 큰지 비교하여 정렬한다.

 

 

 

 

 

ArrayList의 정렬

 

1. Comparable과  Comparator 사용 시  공통점

 

- 둘다 인터페이스이기 때문에 메소드를 Override 해줘야 한다.

 

- 파라미터를 요구한다.

 

 

2. Comparable과  Comparator 사용 시 차이점

 

- Comparable은 compareTo() 메소드를.

  Comparator는 compare() 메소드를 Override 해야 한다.

 

- compareTo() 메소드는 파라미터를 한 개,

  compare() 메소드는 파라미터를 두 개 요구한다.

 

- Collection.sort()로 정렬 시에도 Comparable은 파라미터 한 개,

  Comparator는 파라미터 두 개를 요구한다.

↑ 바로 여기가 어렵다!!!!

 

 

3. Comparable과  Comparator의 정렬기준

 

compareTo() 사용 시 sort에 내가 정렬하고 싶은 ArrayList을 넣는 건 알겠는데,

compare() 사용 시에는 내가 정렬하고 싶은 ArrayList 말고 또 하나의 파라미터를 더 넣어야 한단다.

대체 뭘 넣으라는 걸까??

 

 

답은 이 둘의 정렬 방식이 다르다는 데 있다.

정렬이라는 건 '비교'하는 과정을 필수로 요구한다.

둘은 서로 다른 비교기준을 가지는데, 다음과 같다.

 

 

Comparable의 비교기준: 자기자신 vs 정렬할 객체

Comparator의 비교기준: Comparator 객체 vs 정렬할 객체

 

 

이 차이로 인해 compare는 sort 시 정렬할 리스트뿐 아니라
'Comparator 객체'라는 비교기준이 될 파라미터를 생성해 함께 넣어주어야 하는 것이다.

 

 

Java API 매뉴얼에서 두 메소드가 각각 어떤 형태의 파라미터를 요구하는지 자세히 확인할 수 있다.

🔗Java 8 API 매뉴얼 https://docs.oracle.com/javase/8/docs/api/

 

 

4. Comparator객체의 예시

 

Comparator객체를 만든다는 건 쉽게 말해,
1. compare() 메소드를 오버라이딩한 클래스를 하나 또는 여러 개 만들어 놓고,

2. 원하는 것을 sort의 두번째 파라미터로 집어넣어
3. 커스터마이징한 기준으로 정렬되게 하는 것이다.

 

 

예를 들어 Age에는 내림차순, Name에는 오름차순 정렬을 사용하고 싶다면, 아래와 같이 두 클래스를 만든다.

참고로 아래 리턴값에 쓰이는 compareTo() 메소드는 문자열을 매개변수로 하는 다른 메소드이니 헷갈리지 말자.

import java.util.Comparator;

//PersonAgeComparator에 주고 싶은 정렬기준을 커스터마이징
public class PersonAgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p2.getAge() - p1.getAge();
    }
}

//PersonNameComparator에 주고 싶은 정렬기준을 커스터마이징
public class PersonNameComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getName().compareTo(p2.getName());
    }
}

 

 

그리고 적용하면 각각 다른 기준으로 정렬된다.

List<Person> people = new ArrayList<>();

Person person1 = new Person("John", 25);
Person person2 = new Person("Jane", 30);
Person person3 = new Person("Bob", 20);

people.add(person1);
people.add(person2);
people.add(person3);

Collections.sort(people, new PersonAgeComparator()); //나이를 기준으로 내림차순
Collections.sort(people, new PersonNameComparator()); //이름을 기준으로 오름차순

 

 

 

 

 


참고

🔗 https://st-lab.tistory.com/243

반응형