Java 코딩 테스트 준비 - 정렬하는 방법, Comparable와 Comparator

기운찬곰·2023년 10월 4일
1
post-thumbnail

Overview

자바에서는 정렬하는 방법이 여러가지가 있고, 특히 좀 복잡한 정렬이 필요한 경우에는 어렵기도 하다... 따라서 이에 대해 잘 알아둘 필요가 있다.


정렬하는 방법

Arrays.sort()

Arrays.sort()로 int 배열을 인자로 전달하면 오름차순으로 정렬됩니다.

int[] arr = {1, 26, 17, 25, 99, 44, 303};
Arrays.sort(arr);
System.out.println("Sorted arr[] : " + Arrays.toString(arr)); // [1, 17, 25, 26, 44, 99, 303]

내림차순 정렬이 필요한 경우, sort()의 인자에 추가로 Collections.reverseOrder()를 전달해야 합니다. 참고로, Collections.reverseOrder()는 Comparator 객체이다. Comparator는 직접 구현할 수 있지만, 미리 정의된 Collections 함수를 사용하는 것이다.

Arrays.sort(arr, Collections.reverseOrder());

내림차순 Comparator를 직접 구현하려면 다음과 같이 할 수 있습니다.

Arrays.sort(arr, new Comparator<Integer>() {
    @Override
    public int compare(Integer i1, Integer i2) {
        return i2 - i1;
    }
});

위 코드는 Lambda를 사용하여 이렇게 더 짧게 구현할 수 있습니다. 이 방식이 최고인듯??

Arrays.sort(arr, (i1, i2) -> i2 - i1);

Collections.sort()

리스트 같은 컬렉션을 정렬할 때는 Collections.sort()를 사용할 수 있다.

List<String> list = new LinkedList<String>();
list.add(“김철수”);
list.add(“김영희”);

Collections.sort(list);

내림차순 정렬은 더 쉬운 편이다. reverse() 라는게 따로 있다.

Collections.reverse(list);

아니면 마찬가지로 이렇게도 가능하다.

Collections.sort(list, Collections.reverseOrder());

List.sort()

참고로, 리스트 같은 경우는 자체 sort 메서드가 있다. 따라서 굳이 Collections.sort()를 사용하지 않아도 된다. Java 8 이후에 생겼다고 함.

List<String> list = new LinkedList<String>();
list.add(“김철수”);
list.add(“김영희”);

list.sort();

Comparable와 Comparator

자바 정렬을 제대로 이해하려면 Comparable와 Comparator을 알아야 한다. 그리고... 객체 정렬 같이 복잡한 정렬이 필요한 경우도 이 개념에 대해 알고 있어야 된다.

Comparable과 Comparator는 모두 인터페이스(interface)라는 것이다. 즉, Comparable 혹은 Comparator을 사용하고자 한다면 인터페이스 내에 선언된 메소드를 '반드시 구현'해야한다는 것이다.

Comparator

우선 Comparator부터 살펴보자. Comparator이 더 자주 사용되는거 같아서...

Comparator 인터페이스를 쓰려면 compare 메서드를 구현해야 한다. 특히, Comparator를 사용할때는 익명 객체(클래스)를 활용한다. 익명 객체는 쉽게 말해서 '이름이 정의되지 않은 객체'를 의미한다.

Arrays.sort(arr, new Comparator<Integer>() {
    @Override
    public int compare(Integer i1, Integer i2) {
        return i2 - i1;
    }
});

이를 객체 정렬에 적용하면 다음과 같이 사용할 수 있다. 아래는 Student 객체에 학급에 대한 프로퍼티로 정렬을 하는 예시이다.

import java.util.Comparator;
 
public class Test {
	public static void main(String[] args) {
    	ArrayList<Student> list = new ArrayList<>();
        list.add(new Student(12, 1));
        list.add(new Student(13, 3));
        list.add(new Student(11, 2));
    
		Comparator<Student> StudentClassNumberComp = new Comparator<Student>() {
			@Override
			public int compare(Student o1, Student o2) {
				return o1.classNumber - o2.classNumber;
			}
		};
        
        Collections.sort(list, StudentClassNumberComp);
	}
 
}
 
 
// 외부에서 익명 객체로 Comparator가 생성되기 때문에 클래스에서 Comparator을 구현 할 필요가 없어진다.
class Student {
 
	int age;			// 나이
	int classNumber;	// 학급
	
	Student(int age, int classNumber) {
		this.age = age;
		this.classNumber = classNumber;
	}
 
}

Comparable

Comparable 인터페이스를 쓰려면 compareTo 메소드를 구현해야한다. Comparable의 compareTo(T o) 메소드는 파라미터(매개변수)가 한 개이고, Comparator의 compare(T o1, T o2) 메소드는 파라미터가 두개라는 차이가 있다.

왜 이렇게 구분되는걸까? Comparable은 "자기 자신과 매개변수 객체를 비교"하는 것이고, Comparator는 "두 매개변수 객체를 비교"한다는 것이다. 즉, 본질적으로 비교한다는 것 자체는 같지만, 비교 대상이 다르다는 것이다. 또 다른 차이점이라면 Comparable은 lang패키지에 있기 때문에 import 를 해줄 필요가 없지만, Comparator는 util패키지에 있다.

class Student implements Comparable<Student> {
 
	int age;			// 나이
	int classNumber;	// 학급
	
	Student(int age, int classNumber) {
		this.age = age;
		this.classNumber = classNumber;
	}
	
	@Override
	public int compareTo(Student o) {
 
		/*
		 * 만약 자신의 age가 o의 age보다 크다면 양수가 반환 될 것이고,
		 * 같다면 0을, 작다면 음수를 반환할 것이다.
		 */
		return this.age - o.age;
	}
}

그러면 이를 sort하면 자동으로 해당 compareTo 정의에 따라 sort가 된다.

ArrayList<Student> list = new ArrayList<>();
list.add(new Student(12, 1));
list.add(new Student(13, 3));
list.add(new Student(11, 2));
        
Collections.sort(list);
profile
velog ckstn0777 부계정 블로그 입니다. 프론트 개발 이외의 공부 내용을 기록합니다. 취업준비 공부 내용 정리도 합니다.

0개의 댓글

관련 채용 정보