[Java] 비교 메서드를 이용하여 원하는 기준으로 정렬하기

pintegral·2023년 3월 7일
0

Java

목록 보기
3/3
post-thumbnail

I. Object 비교하기

비교 라이브러리가 여러 종류라 평소에 헷갈렸던 개념들을 정리하고 가려고 한다.
비교하는 Object에는 String ClassWrapper Class도 포함된다.

compareTo와 compare 차이점?

1. Comparable 인터페이스의 compareTo()

Comparable이란?

java.lang.Comparable< T>

공식문서에 의하면 클래스의 자연 순서, 즉 기본 정렬 기준이 되는 메서드를 정의하는 인터페이스이다.
(This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method.)

compareTo 사용 예시

Comparable 인터페이스를 구현한 뒤에, 내부에 있는 compareTo 메서드를 원하는 정렬 기준대로 구현하여 사용한다.

Object Class 비교 메서드 정의
class Student implements Comparable<Student> {
	int grade;
	// compareTo 메서드 오버라이드
    @Override
    public int compareTo(Student anotherStudent) {
    	return Integer.compare(grade, anotherStudent.grade);
    }
}
Wrapper Class(Integer, Dobule) 비교
  public static void main(String[] args){

        Integer x = 3;
        Integer y = 4;
        Double z = 1.0;

        System.out.println( x.compareTo(y) ); // return -1
        System.out.println( x.compareTo(3) ); // return 0
        System.out.println( x.compareTo(2) ); // return 1
        System.out.println( z.compareTo(2.7) ); // return -1

    }
String Class 비교
   public static void main(String[] args){

       String str = "abcd";

       // 1) 비교대상에 문자열이 포함되어있을 경우
       System.out.println( str.compareTo("abcd") ); // return 0 (같은 경우는 숫자나 문자나 0을 리턴)
       System.out.println( str.compareTo("ab") ); // return 2
       System.out.println( str.compareTo("a") ); // return 3
       System.out.println( str.compareTo("c") ); // return -2       
       System.out.println( "".compareTo(str) ); // return -4

       // 2) 비교대상과 전혀 다른 문자열인 경우
       System.out.println( str.compareTo("zefd") ); // return -25
       System.out.println( str.compareTo("zEFd") ); // return -25
       System.out.println( str.compareTo("ABCD") ); // return 32
   }

2. Comparator 인터페이스의 compare()

Comparator란?

java.util.Comparator< T>

공식문서 에 의하면 객체 Collection에 대해 더 정확한 정렬 기준을 정하는 인터페이스이다.
(to allow precise control over the sort order.)

즉, Comparator는 클래스의 기본 정렬 기준을 정의한다면, Comparable은 기본 정렬 기준과 다른 방식으로 정렬하고 싶은 경우 전체 정렬 기준을 정의하는 인터페이스이다.

compare 사용 예시

주로 Collections의 정렬 관련 메서드에 Comparator를 익명 객체로 넣어 정렬 기준을 변경하는 데 사용한다.

Arrays.sort(room, new Comparator<String>() {
	@Override
    public int compare(String s1, String s2) {
    	return s1.compare(s2);
    }
}

3. compareTo와 compare 비교에 대한 결론

  • compareTo자기 자신과 매개변수를 비교하는 Comparable 메서드로, 클래스의 기본 정렬 기준을 정의하기 때문에 반드시 구현해야 한다.
  • 이와 달리 compare두 매개변수 객체를 비교하는 Comparator메서드로, 정렬 기준 재정의 시 오버라이드하여 사용하는 메서드이다.

Byte, Double, Integer, Float, Long, Short의 숫자형 비교는 Comparable의 compareTo 메서드로 비교가능하다.

그렇다면 Wrapper Class가 아닌 Primitive Type의 정수형은 어떻게 비교해야 할까?

II. Integer가 아닌 int 타입 정수형 비교하기

1. Comparator.comparingInt()

comparingInt 메서드란?

static <T> Comparator<T> comparingInt(ToIntFunction <T> keyExtractor)

comparingInt 메서드 사용 예시

Object Collection 오름차순 정렬하기
public static void main(String[] args)
    {
  
        // create some user objects
        User u1 = new User("Aaman", 25);
        User u2 = new User("Joyita", 22);
        User u3 = new User("Suvam", 28);
        User u4 = new User("mahafuj", 25);
  
        // before sort
        List<User> list
            = Arrays.asList(u2, u1, u4, u3);
        System.out.println("Before Sort:");
        list.forEach(User
                     -> System.out.println("User age "
                                           + User.getAge()));
  
  		// comparingInt로 User의 age 비교
        Collections.sort(list,
                         Comparator.comparingInt(
                             User::getAge));
        System.out.println("\nAfterSort:");
        list.forEach(User
                     -> System.out.println("User age "
                                           + User.getAge()));
    }
}
class User implements Comparable<User> {
    public String name;
    public int age;
  
    public User(String name, int age)
    {
        this.name = name;
        this.age = age;
    }
  
    public int compareTo(User u1)
    {
        return name.compareTo(u1.name);
    }
  
    public String getName()
    {
        return name;
    }
  
    public void setName(String name)
    {
        this.name = name;
    }
  
    public int getAge()
    {
        return age;
    }
  
    public void setAge(int age)
    {
        this.age = age;
    }
  
    @Override
    public String toString()
    {
        return "User [name=" + name
            + ", age=" + age + "]";
    }
}

2차원 배열 첫 번째 요소만 고려하여 정렬하기

// int[][] arr
Arrays.sort(arr, Comparator.comparingInt(o1 -> o1[0]));

2.Integer.compare()

Integer 인터페이스의 compare 메서드란?

    /**
     * Compares two {@code int} values numerically.
     * The value returned is identical to what would be returned by:
     * <pre>
     *    Integer.valueOf(x).compareTo(Integer.valueOf(y))
     * </pre>
     *
     * @param  x the first {@code int} to compare
     * @param  y the second {@code int} to compare
     * @return the value {@code 0} if {@code x == y};
     *         a value less than {@code 0} if {@code x < y}; and
     *         a value greater than {@code 0} if {@code x > y}
     * @since 1.7
     */
    public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

두 정수형 타입의 값들을 비교하여 -1, 0, 1을 반환하는 메서드다.

  • 첫 번째 인자 < 두 번째 인자: -1
  • 첫 번째 인자 = 두 번째 인자: 0
  • 첫 번째 인자 > 두 번째 인자: 1

Integer.compare 사용 예시

단순 두 정수 비교하기
  public static void main(String... args) {
    System.out.println(Integer.compare(1, 2)); // return -1
 	System.out.println(Integer.compare(2, 2)); // return 0
    System.out.println(Integer.compare(3, 2)); // return 1
  }
2차원 배열 두 번째 요소까지 고려하여 정렬하기
// int[][] arr
   Arrays.sort(dungeons, (o1,o2) -> {
            // 첫 번째 요소 같을 시 두 번째 요소 비교
            if(o1[0] == o2[0]){
                // 두 번째 요소 비교하여 오름차순 정렬
                return Integer.compare(o1[1],o2[1]); 
             // 첫 번째 요소 같지 않을 시
            } else {
                // 첫 번째 요소 비교하여 내림차순 정렬
                return Integer.compare(o2[0], o1[0]); 
            }
        });        

References

profile
문제를 끝까지 해결하려는 집념의 개발자

0개의 댓글