[Coding Test]Comparable & Comparator

Euiyeon Park·2025년 2월 7일

CodingTest / Algorithm

목록 보기
1/1
post-thumbnail

LeetCode 로그 파일 재정렬

https://leetcode.com/problems/reorder-data-in-log-files/description/

🍀제약 조건

  1. 로그 가장 앞부분은 식별자로, 순서에 영향을 끼치지 않는다.
  2. 문자로 구성된 로그가 숫자 로그보다 앞에오며, 문자 로그는 사전순으로 한다.
  3. 문자가 동일한 경우에는 식별자순으로 한다.
  4. 숫자 로그는 입력 순서대로 한다.

🍀문제의 핵심 코드

Collections.sort(letterLogs, new Comparator<String>(){
    public int compare(String l1, String l2){

        // 각 로그를 식별자와 내용으로 분리
        String[] log1 = l1.split(" ", 2);    // ["id2", "art can"]
        String[] log2 = l2.split(" ", 2);

        // 식별자를 제외하고 두 로그의 내용을 비교한다.
        // 💡이 때, 로그의 내용은 문자열(String)이므로 compareTo()를 이용한다.
        int result = log1[1].compareTo(log2[1]);

        // 로그의 내용이 같으면 식별자로 비교한다.
        if(result == 0){
            result = log1[0].compareTo(log2[0]);
        }

        return result;
      }
});
  • 이 문제의 핵심 부분은 직접 Comparator를 구현하여,
    문제가 요구하는 방식으로 주어진 로그(문자열)을 정렬하는 것이었다.
  • 그래서 ComparableComparator에 대한 학습이 더 필요함을 느꼈다 .. !
  • 사실 CodingTest와 관련된 알고리즘이나 자료구조에 대한 포스트보다는
    자바에 대한 포스트인 것 같지만 쨋든 코테 풀다가 포스팅하는거니까 !

정렬이란,

  • 정렬이란 두 대상을 비교해서 자리바꿈을 반복하는 것을 의미한다.
  • 즉, 정렬대상정렬 기준이 필요하다.
  • 정렬 기준을 주지 않을 경우, Comparable에 의해 정렬된다.

ComparableComparator는 자바에서 객체를 정렬할 때 사용하는 두 가지 인터페이스로,
정렬 기준을 제공하는 인터페이스이다.

🍀Comparable

  • 기본 정렬기준을 구현하는데 사용한다.
  • 객체 자체가 어떻게 정렬될지 클래스 내부에서 결정(객체 자체에 정렬 기준을 정의 가능)
  • Comparable을 구현한 클래스는 정렬이 가능하다는 것을 의미한다.
  • Comparable을 구현한 클래스들은 같은 타입의 인스턴스끼리 서로 비교할 수 있는 클래스들이다.
    • Wrapper클래스(Integer, Double .. 등), String, Data
  • compareTo(T other) 메서드를 오버라이딩 하여 정렬 기준을 설정한다.

객체 자체에서 정렬 기준을 정의한다는게 뭔말임?

  • 해당 객체가 기본적으로 어떤 기준으로 정렬될 지 직접 정의할 수 있다.
  • Comparable 인터페이스를 객체(Class)내부에서 직접 구현해 정렬 기준을 설정할 수 있다.

.. 걍 코드로 직접 보는게 이해가 빠르다!

1. Comparable이 없는 경우

  • Comparable을 구현하지 않으면, Person객체를 정렬하려고 할때
    Collections.sort()를 사용할 수 없다.(정렬 기준❌)
class Person{
	String name;
    int age;
    
    public Person(String name, int age){
    	this.name = name;
        this.age = age;
    }
}

public class Main {
	public static void main(String[] args){
    	List<Person> people = new ArrayList<>();
        people.add(new Person("의연", 30);
        people.add(new Person("한얼", 29);
        people.add(new Person("진호", 31);
        people.add(new Person("소윤", 26);
        people.add(new Person("병중", 27);
       	
        // ⚠️ 컴파일 오류 발생 - Person에 정렬 기준이 없다.❌
        Collections.sort(people);
	}
}

2. Comparable을 구현한 경우

  • Comparable을 구현하면, Person객체가 어떤 기준으로 정렬될지 직접 정의 가능⭕
  • Comparable을 구현하면 객체가 스스로 "나는 이런 기준으로 정렬되어야 해!"하는 것과 같음
class Person implements Comparable<Person>{
    String name;
    int age;

    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    
    // 📌객체 자체의 기본 정렬 기준을 정의 - 나이 오름차순
    @Override
    public int compareTo(Person other){
    	return Integer.compare(this.age, other.age);\
    }
}

public class Main{
	public static void main(String[] args){
    	List<Person> people = new ArrayList<>();
        people.add(new Person("의연", 30);
        people.add(new Person("한얼", 29);
        people.add(new Person("진호", 31);
        people.add(new Person("소윤", 26);
        people.add(new Person("병중", 27);
        
        Collections.sort(people);
    }
}

🍀Comparator

  • 기본 정렬 기준외에 다른 기준으로 정렬하고자할 때 사용한다.
  • 객체에 대한 별도의 정렬 기준을 정의할 때 사용한다.(외부에서 객체의 정렬 기준을 정의)
  • 객체(클래스) 자체 정렬 기준을 정의하는 대신, 별도의 클래스를 만들어 다양한 기준으로 정렬
  • compare(T obj1, T obj2) 메서드를 오버라이딩 해 원하는 기준을 설정한다.

객체에 대한 별도의 정렬 기준을 정의한다는게 뭔말임?

  • 이것도 코드로 보는게 이해가 빠르다.
class NameComparator implements Comparator<Person> {
	@Override
    public int compare(Person p1, Person p2){
    	return p1.name.compareTo(p2.name);
    }
}

public class Main{
	public static void main(String[] args){
    	List<Person> people = new ArrayList<>();
      	people.add(new Person("의연", 30);
        people.add(new Person("한얼", 29);
        people.add(new Person("진호", 31);
        people.add(new Person("소윤", 26);
        people.add(new Person("병중", 27);
        
        // ✅ Comparator를 사용한 정렬
        people.sort(new NameComparator());
   }
}

🍀정리

1. Comparable

  • 클래스 내부에 직접 정렬 기준을 정의한다.(객체 자체에서 정렬 기준을 정의)
  • compareTo(T other) 메서드를 오버라이딩해서 정렬 기준을 정의한다.

2. Comparator

  • 클래스 외부에서 정렬 기준을 정의한다.
  • 정렬 대상과 함께 Comparator를 주면 해당 Comparator를 기준으로 정렬한다.
  • compare(T obj1, T ojb2) 메서드를 오버라이딩해서 정렬 기준을 정의한다.
profile
"개발자는 해결사이자 발견자이다✨" - Michael C. Feathers

0개의 댓글