[JAVA] 정렬 및 비교

SuIn Woo·2023년 2월 1일
4
post-thumbnail

서론

Java라는 언어를 다루면서 같은 자료형, 다른 자료형, 객체 등 다양한 정렬비교를 하게된다. 최근 알고리즘을 풀면서 정렬과 비교를 많이 사용하고 있지만 헷갈리는 부분이 있어 코드 예제를 통해 간단히 정리해보려고 한다.


예제 클래스

아래의 클래스는 본 글에서 사용할 간단한 예제 클래스입니다.

People.java

/**
* People 클래스
* 사람의 이름과 나이를 저장하는 클래스
* @Param name(이름), age(나이)
*/
public class People{
    private String name;
    private int age;

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

Test.java

/**
* Test 클래스 main 부분
* People 객체의 리스트에 이름과 나이가 다른 People 객체를 담을 예정
*/
main { 
		List<People> peoples = new ArrayList<>();
		peoples.add(new People("민준", 20));
		peoples.add(new People("서준", 25));
		peoples.add(new People("도윤", 23));
		peoples.add(new People("민수", 28));
		peoples.add(new People("건우", 27));
		peoples.add(new People("철수", 30));
}

1. 비교

  • equals() (Reference Type 비교)
    문자열을 비롯한 참조 타입을 비교할 때 사용하는 equlas()의 경우 메서드 형태이며 사용시 참조 타입이 가르키는 값을 비교할 때 사용한다.

  • == (Primitive Type 비교)
    ==는 자바에서 기본적으로 제공하는 연산자 중 하나이며 기본 자료형을 비교할 때는 값을, 참조 자료형을 비교할 때는 주소값을 비교한다.

    String str = new String("민준");
    System.out.println(peoples.get(0).name == str); 
    // -> false
    System.out.println(peoples.get(0).name.equals(str)); 
    // -> true

2. 정렬

  • 예제 클래스의 이름, 나이 정렬
    이름이나 나이를 새로운 배열에 저장하여 Arrays.sort()를 사용해 정렬 할 수 있다.
    	int[] ageArr = new int[]{20, 25, 23, 28, 27, 30};
    	Arrays.sort(ageArr);

  • 객체 정렬
    compareTo메소드나 compare메소드를 통해 기준을 잡은 후 Collections를 통해 정렬할 수 있다.

    	@Override
    	public int compareTo(People o) {
      
    		if(this.age > o.age) {
    			return 1; // 양수면 어떤수든 상관없음
    		}
    		else if(this.age == o.age) {
    			return 0;
    		}
    		else {
    			return -1; // 음수면 어떤수든 상관없음
    		}
    	}
    
    	@Override
        public int compare(People o1, People o2) {
    
            if(o1.age > o2.age) {
                return 1;
            }
            else if(o1.age == o2.age) {
                return 0;
            }
            else {
                return -1;
            }
        }

3. Comparable, Comparator

  • 공통 부분

    • 인터페이스
      Comparable과 Comparator는 모두 인터페이스라는 것이다.

      즉, Comparable 혹은 Comparator을 사용하고자 한다면 인터페이스 내에 선언된 메소드를 반드시 구현해야한다.

      아래 API 문서를 통해 어떤 메서드를 구현해야하는지 알아보자.

      [Comparable]

      Comparable (Java Platform SE 8 )

      API 문서를 보면 Comparable 인터페이스에는 compareTo(T o) 메소드 하나가 선언되어있는 것을 볼 수 있다. 이 말은 우리가 만약 Comparable을 사용하고자 한다면 compareTo 메소드를 재정의(Override)을 해주어야 한다.

      [Comparator]

      Comparator (Java Platform SE 8 )

      Comparator를 보면 선언 된 메소드가 많지만, 실질적으로 구현해야 하는 것은 compare(T o1, T o2) 이다.

  • Comparable

    • 특징
      • java.lang package
      • 객체의 정렬기준을 정해줄 때 사용한다.
      • Comparable 인터페이스의 구현체는 compareTo메서드를 구현해야 한다.

    • comparTo(T o)

      int compareTo(T o)

      Parameters:

      o - 비교될 오브젝트( 객체 )이다.

      Returns:
      비교되는 오브젝트 기준

      비교되는 o 오브젝트보다 작으면 -1(음수), 같으면 0, 크면 1(양수)를 반환한다.

  • Comparator

    • 특징

      • java.util package
      • 이미 정해진 정렬기준 외 다른 정렬기준을 사용하고 싶을때 사용한다.
      • Comparator 인터페이스의 구현체는 compare메서드를 구현해야 한다.
      • Comparator 인터페이스의 구현체는 그 자체가 정렬자로 사용된다. (정렬기준)
    • compare(T o1, T o2) → 익명객체 사용

      int compare(T o1, T o2)

      Parameters:

      o1 - 비교될 첫 번째 오브젝트다

      o2 - 비교될 두 번째 오브젝트다

      Returns:
      두 객체를 비교

      o1이 o2 오브젝트보다 작으면 -1(음수), 같으면 0, 크면 1(양수)를 반환한다.

    • 익명객체 == 무명클래스

      • 사용 목적 : UI 이벤트 처리 객체 / 스레드 객체를 간편하게 생성하기 위해 많이 활용
      • 사용 용도 : 필드 / 로컬변수 의 초기값, 매개변수의 매개값으로 사용
      • 단독으로 생성 불가, 클래스 상속 or 인터페이스 구현해서 사용 가능 !
      • 재사용 목적이 아닌 1번만 사용 하려고 할 때 쓴다.

4. 결론

  • 비교와 정렬은 코딩을 하면서 많이 사용하는 부분이므로 자주 써보는 것이 중요
  • ==equals()를 사용할 땐 객체와 값 중 어떤 것을 비교하려고 하는지 미리 알고 써야함
  • Comparable / Comparator 는 모두 객체를 비교하기 위한 기능의 인터페이스
  • 정렬(sort)와 함께 사용 될 때
    • Comparable : 오름차순 정렬만 할 때 주로 사용
      기준이 되는 객체와 비교
    • Comparator : 내림차순이나 특별한 기준에 따라 비교할 때 주로 사용
      내가 비교하고싶은 객체 두개를 비교

참고 자료

[Java] 객체 정렬하기 1부 - Comparable vs Comparator
자바 [JAVA] - Comparable 과 Comparator의 이해
Java 기본(5) - Comparable / Comparator 비교

4개의 댓글

comment-user-thumbnail
2023년 2월 4일

char 도 equals를 써서 오류났던 적이 있는데 깔끔하게 정리해줘서 좋았습니다.
comparable 과 comparator 를 새로 알게되어 더 좋은 코딩을 할 것 같아요!!
글 잘 읽었습니다.

답글 달기
comment-user-thumbnail
2023년 2월 5일

잘 읽었습니다! comparable과 comparator가 헷갈릴 수 있는데 공통 부분과 각각의 특징을 따로 설명해준 점이 좋았습니다

답글 달기
comment-user-thumbnail
2023년 2월 5일

같은 주제로 포스팅을 한 경험이 있는데요 관점에 따라 이렇게 다른 글이 나오는게 신기하네요!
정리하면서 저도 햇갈렸던 부분을 명확하게 알 수 있었던 것 같습니다~!!

답글 달기
comment-user-thumbnail
2023년 2월 8일

깔끔한 정리인 것 같습니다!
compareTo 의 앞 뒤 순서와 -1, 0, 1 결과를 외우는 요령이 제각각 인 것 같은데,
전 o1.compareTo(o2) < 0 이라면, o1 < o2 형태로 생각해서 o1이 더 작은지(문자라면 아스키 코드 값이 더 작은지 = 사전순 더 빠른지) 로 생각합니다.
좋은 글 잘 읽었습니다.

답글 달기