티스토리 뷰

자바가 기본으로 제공하는 Integer,String 같은 객체를 제외하고 직접 만든 객체를 정렬하려면 어떻게 해야할까? 내가 만든 객체이기 때문에 정렬을 할 때 내가 만든 두 객체 중에 어떤 객체가 더 큰지 알려줄 방법이 있어야 한다.

이때는 Comparable 인터페이스를 구현하면 된다. 이 인터페이스는 이름 그대로 비교 가능한,비교할 수 있는 이라는 뜻으로, 객체에 비교 기능을 추가해 준다.

 

public interface Comparable<T> {
 public int compareTo(T o);
}

 

자기 자신과 인수로 넘어온 객체를 비교해서 반환하면된다.

  • 현재 객체가 인수로 주어진 객체보다 더 작으면 음수 예 -1
  • 두 객체의 크기가 같으면 0
  • 현재 객체가 인수로 주어진 객체보다 더 크면 양수 예 1
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 void setId(String id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "MyUser{" +
                "id='" + id + '\'' +
                ", age=" + age +
                '}';
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int compareTo(MyUser o) {
        if(this.age < o.age) {
            return -1;
        } else if(this.age == o.age) {
            return 0;
        } else {
            return 1;
        }
    }
}

 

MyUser 가 Comparable 인터페이스를 구현한 것을 확인할 수 있다.

compareTo() 구현을 보면 여기서는 정렬의 기준을 나이(age)로 정했다.

MyUser 클래스의 기본 정렬 방식을 나이 오름차순으로 정한 것 이다.

Comparable을 통해 구현한 순서를 자연 순서(Natural Ordering)라 한다.

 

public class SortMain3 {
    public static void main(String[] args) {
        MyUser myUser1 = new MyUser("a", 30);
        MyUser myUser2 = new MyUser("b", 20);
        MyUser myUser3 = new MyUser("c", 10);

        MyUser[] array = {myUser1, myUser2, myUser3};
        System.out.println("기본 데이터");
        System.out.println(Arrays.toString(array));

        System.out.println("Comparable 기본 정렬");
        Arrays.sort(array);
        System.out.println(Arrays.toString(array));
    }
}

 

Arrays.Sort(array)

기본 정렬을 시도한다. 이때는 객체가 스스로 가지고 있는 Comparable 인터페이스를 사용해서 비교한다.

MyUser가 구현한 대로 나이(age) 오름차순으로 정렬된 것을 확인할 수 있다. MyUser의 자연적인 순서를 사용했다.

 

다른 방식으로 정렬

만약 객체가 가지고 있는 Comparable 기본 정렬이 아니라 다른 정렬을 사용하고 싶다면 어떻게 해야할까?

나이가 아니라 아이디로 비교하는 예제를 추가로 만들어보자.

 

아이디로 비교할 수 있는 IdComparator을 하나 만들어 보자.

import java.util.Comparator;

public class IdComparator implements Comparator<MyUser> {
    @Override
    public int compare(MyUser o1, MyUser o2) {
        return o1.getId().compareTo(o2.getId());
    }
}

 

o 아이디를 기준으로 정렬할 때 사용한다.

 

 

import java.util.Arrays;

public class SortMain4 {
    public static void main(String[] args) {
        MyUser myUser1 = new MyUser("a", 30);
        MyUser myUser2 = new MyUser("b", 20);
        MyUser myUser3 = new MyUser("c", 10);

        MyUser[] array = {myUser1, myUser2, myUser3};
        System.out.println("기본 데이터");
        System.out.println(Arrays.toString(array));

        System.out.println("Comparable 기본 정렬");
        Arrays.sort(array);
        System.out.println(Arrays.toString(array));

        //추가
        System.out.println("IdComparator 정렬");
        Arrays.sort(array,new IdComparator());
        System.out.println(Arrays.toString(array));

        System.out.println("IdComparator().reserved() 정렬");
        Arrays.sort(array,new IdComparator().reversed());
        System.out.println(Arrays.toString(array));
    }
}

 

 

 

Arrays.sort(array,Comparator)

기본 정렬이 아니라 정렬 방식을 지정하고 싶다면 Arrays.sort의 인자로 비교자(Compartor)을 만들어 넘겨 주면 된다.

이렇게 비교자를 따로 전달하면 객체가 기본으로 가지고 있는 Comparable을 무시하고, 별도로 전달한 비교자를 사용해서 정렬한다.

 

여기서는 기본으로 나이를 기준으로 정렬 하지만, 아이디로 정렬하고 싶다면 IdComparator을 넘겨주면 된다.

 

 

주의!!!

만약 Comparable도 구현하지 않고, Comparator도 제공하지 않고, 직접 만든 객체를 Arrays.sort() 하면 다음과 같은 런타임 오류가 발생한다.

java.lang.ClassCastException: class collection.compare.MyUser cannot be cast to 
class java.lang.Comparable

 

 

 

정리

 

객체의 기본 정렬 방법은 객체에 Comparable을 구현해서 정의한다. 이렇게 하면 객체는 이름 그대로 비교할 수 있는 객체가 되고, 기본 정렬 방법을 가진다. 그런데 기본 정렬 외에 다른 정렬 방법을 사용해야하는 경우 비교자 (Comparator)을 별도로 구현해서 정렬 메서드에 전달하면 된다. 이 경우 전달한 Comparator가 항상 우선권을 가진다.

자바가 제공하는 Integer, String 같은 기본 객체들은 대부분 Comparable을 구현해 두었다.

'Java' 카테고리의 다른 글

Java - Thread 제어와 생명 주기  (0) 2024.08.08
Java - Thread 1  (0) 2024.07.30
Java - 데이터 정렬 1 (Comparable,Comparator)  (0) 2024.06.18
Java - 와일드 카드  (1) 2024.06.13
Java - 제네릭 2  (1) 2024.06.13
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함