일단 시작해보는 블로그

[Java] Comparable, Comparator 본문

개발/Java

[Java] Comparable, Comparator

Selina Park 2019. 9. 4. 11:50

요약

Comparable :

기본적인 정렬 기준으로 정렬. default = 오름차순이지만 내림차순도 있으며, 사전순으로 숫자크기순 등등이 이에 해당된다.

@Override

compareTo(Object o) -> this, o 비교 -> 오름차순이면 뒤에있는 o가 더 커야하므로 this > o 일 때 맞는거니까 양수 return!  

 

Comparator :

기본적인 정렬 기준 이외의 기준으로 정렬하고자 할 때 사용. 그러니까 사전순이 아닌, 여러 조건이 있을 경우라던지, 문자열의 길이 순, 객체내에 접근해서 값을 비교해야한다던지 등등 일 때 사용한다.

@Override

compare(Object o1, Object o2) -> o1, o2비교 -> 오름차순이면 뒤에있는 o2가 더 커야하므로 o1 < o2 일 때 맞는거니까 양수 return!  

 


 

자료구조를 이용 해야할 때, Java의 List, Array 등을 사용한다.

이를 정렬하고자 할 때는 Arrays.sort() 혹은 Collections.sort(), 즉 sort() 메서드를 사용하게 되는데 

누군가가 구현해 놓은 기본정렬 기준에 맞춰서 정렬된다.

 

그럼 내림차순, 기준이 다른 정렬 등을 하려고 할 때는 어떻게 해야할까?

 

다음은 정렬을 담당하는 Java의 인터페이스 Comparable, Comparator 이다.

Comparable (java.lang 패키지)

기본적인 정렬기준을 구현하는데 사용. (compareTo() 추상 메서드)

(여기서 기본적인 정렬 기준이란 (일반적인, 사전순, 숫자순, 오름차순, 내림차순! default는 오름차순이다.))

기본 정렬 기준 이외의 기준으로 정렬하고자 한다면 Comparable을 확장해서 사용 가능하다. 

예를 들면, Man이라는 class의 속성이 String name, int age가 있다고 했을 때, 정렬 기준을 age로 하고 싶다면

Comparable을 클래스로 구현하고 compareTo() 메서드를 override해줘서 정렬 기준을 바꾸면 된다.

return 값에 a.compareTo(b) == -(b.compareTo(a)) 를 만족하게 구성해주면 된다.

아래 예제에서 Man 클래스의 속성 name을 기준으로 정렬하고 싶은데, 

( 예를 들어, 정수값으로 리턴해야하는 상황에서 this.name - man.getName()을 해주면 정수가 리턴되지 않으므로 에러가 뜬다.

이런 상황에서는 this.name.compareTo(man.getName())을 리턴해주면 된다. )

class Man implements Comparable<Man> {
    String name;
    int age;

    Man(String name, int age){
        this.name = name;
        this.age = age;
    }

    public String getName(){
        return this.name;
    }

    public void setName(String name){
        this.name = name;
    }

    public int getAge(){
        return this.age;
    }

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

    public String arrToString(){
        return this.getName() + " " + this.getAge();
    }

    @Override
    public int compareTo(Man man){
        return this.age - man.getAge();
        //return this.name.compareTo(man.getName());
    }
}

 

Comparator (java.util 패키지)

기본 정렬 기준(사전순, 숫자는 오름차순 등) 외에 다른 기준으로 정렬하고자 할 때 사용. (compare() 추상 메서드)

다른 기준이라면 글자의 길이, new BigInteger("123445") 와 같이 객체의 메모리주소를 가지고 있는 자료구조인데, 객체 내에 있는 123445와 같은 값을 기준으로 정렬하고 싶을 때 등을 위한 인터페이스라고 보면 된다.

 

구현은 주로 익명 클래스 Comparator<K>을 사용한다.

 

객체 내의 값을 기준으로 정렬하고자 할 때의 예제

class Man{
    String name;
    int age;
    BigInteger salary;

    Man(String name, int age, BigInteger salary){
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getName(){
        return this.name;
    }

    public void setName(String name){
        this.name = name;
    }

    public int getAge(){
        return this.age;
    }

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

    public BigInteger getSalary(){
        return this.salary;
    }

    public void setAge(BigInteger salary){
        this.salary = salary;
    }

    public String arrToString(){
        return this.getName() + " " + this.getAge() + " " + this.getSalary();
    }
}

public class Solution{
	public static void main(String[] args) {
        Man m1 = new Man("박보검", 26, new BigInteger("2800"));
        Man m2 = new Man("남주혁", 27, new BigInteger("3200"));
        Man m3 = new Man("강하늘", 30, new BigInteger("2800"));
        Man m4 = new Man("강동원", 34, new BigInteger("7000"));
        Man m5 = new Man("류준열", 31, new BigInteger("3900"));

        Man[] manArr = {m1, m2, m3, m4, m5};

        Arrays.sort(manArr, new Comparator<Man>(){
            @Override
            public int compare(Man m1, Man m2){
                return m1.getSalary().intValue() - m2.getSalary().intValue();
            }
        });

        for(Man mi : manArr){
            System.out.println(mi.arrToString());
        }
    }
}

객체 내의 숫자 순으로 정렬

 

다음 문자열의 길이에 따라 정렬하고 싶을 때!

class Man{
    String name;
    int age;
    BigInteger salary;
    String introduce;

    Man(String name, int age, BigInteger salary, String introduce){
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.introduce = introduce;
    }

    public String getName(){
        return this.name;
    }

    public void setName(String name){
        this.name = name;
    }

    public int getAge(){
        return this.age;
    }

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

    public BigInteger getSalary(){
        return this.salary;
    }

    public void setAge(BigInteger salary){
        this.salary = salary;
    }

    public String getIntroduce(){
        return this.introduce;
    }

    public void setIntroduce(String introduce){
        this.introduce = introduce;
    }

    public String arrToString(){
        return this.getName() + " " + this.getAge() + " " + this.getSalary() + " " + this.getIntroduce();
    }
}

public class Solution{
	public static void main(String[] args) {
        Man m1 = new Man("박보검", 26, new BigInteger("2800"), "안녕하세요 저는 박보검입니다 힛~~");
        Man m2 = new Man("남주혁", 27, new BigInteger("3200"), "안녕");
        Man m3 = new Man("강하늘", 30, new BigInteger("2800"), "저는 무한 긍정 강하늘입니다. 여러분 행복해지세요.^8^");
        Man m4 = new Man("강동원", 34, new BigInteger("7000"), "저는 요즘 유튜버에요.");
        Man m5 = new Man("류준열", 31, new BigInteger("3900"), "안녕하세요. 저는 잘생긴애들중에 제일 못생긴 잘생긴 류준열입니다. 뭐래");

        Man[] manArr = {m1, m2, m3, m4, m5};

		//자기소개 제일 길게 한 사람 순으로 정렬
        Arrays.sort(manArr, new Comparator<Man>(){
            @Override
            public int compare(Man m1, Man m2){
                return (m1.getIntroduce().length() - m2.getIntroduce().length()) * -1;
            }
        });

        for(Man mi : manArr){
            System.out.println(mi.arrToString());
        }
    }
}

문자열 길이가 긴 순으로 정렬

 

 

 

 

[REFERENCE]

https://cwondev.tistory.com/15

https://www.geeksforgeeks.org/comparator-interface-java/

Comments