Arrays.sort() VS Collections.sort() / Comparable VS Comparator

최수연·2026년 2월 7일

Java 코딩테스트

목록 보기
8/8

이 문서는 자바를 공부하면서 가장 헷갈렸던 부분, 정리되지 않았던 부분인 연속 자료형의 정렬에 대한 정리 문서이다.


Arrays.sort() vs Collections.sort()

자바에서 정렬을 할 때에는 크게 두 가지 방법이 있다.

  • Arrays.sort()
  • Collections.sort()

둘 다 정렬할 때 쓰이지만 적용 대상내부 동작에서 차이가 있다.


1. Arrays.sort()

  • 대상 : 배열(array)
  • 라이브러리 : java.util.Arrays
public static void main(String[] args) {
	int[] arry = {5, 3, 1, 4, 2};
	
	Arrays.sort(arry);    // 기본 오름차순 정렬
	System.out.println(Arrays.toString(arry));    // [1, 2, 3, 4, 5]
	
	Arrays.sort(arry, Comparator.reverseOrder());    // Comparator 내림차순 정렬
	System.out.println(Arrays.toString(arry));    // [5, 4, 3, 2, 1]
}

⇒ Arrays.sort()에서도 Comparator가 사용 가능하다.


2. Collections.sort()

  • 대상 : 리스트(List)
  • 라이브러리 : java.util.Collections
public static void main(String[] args) {
	List<Integer> list = Arrays.asList(5, 3, 1, 4, 2);
	
	Collections.sort(list);
	System.out.println(Arrays.toString(list));    // [1, 2, 3, 4 ,5]
	
	Collections.sort(list, Comparator.reverseOrder());    // Comparator 내림차순 정렬
	System.out.println(Arryas.toString(list));    // [5, 4, 3, 2, 1]
}



정리

적용 대상배열(Array)리스트(List)
소속 클래스java.util.Arraysjava.util.Collections
반환 값없음 (원본 배열 수정)없음 (원본 리스트 수정)
지원 타입기본형 배열(int[], String[] 등), 객체 배열객체 타입 리스트(List)
정렬 기준기본 오름차순, Comparator 가능기본 오름차순, Comparator 가능

참고문서) [Java 기초] Arrays.sort() vs Collections.sort() 차이 정리




Comparable vs Comparator

자바에서 컬렉션을 정렬하는 방법에는 두 가지가 있다.

  • Comparable 인터페이스에 compareTo 구현

  • Comparator 인터페이스에 compare 구현


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

Comparable 인터페이스는 객체 자체에 기본적인 정렬 기준을 설정하는 인터페이스다. 해당 클래스가 Comparable<클래스명>을 implements하고, compareTo() 메서드를 Override하면 기본 정렬 기준을 정의할 수 있다.

public class Student implements Comparable<Student> {
	private int StudentNo;
	private String name;
	private String number;
	private int age;
	private String major;
	
	// 생성자 및 getter, setter
	
	@Override
	public int compareTo(Student o) {
		return this.getStudentNo() - o.getStudentNo();    // 학번 오름차순 정렬
	}
}



Comparable<>을 implements해야 하는 이유?

⇒ Integer, Double과 같은 자바가 기존에 Comparable을 구현해놓은 Wrapper 클래스가 아닌 사용자가 직접 생성한 클래스 객체는 컴퓨터가 어떤 멤버 변수를 기준으로 정렬할 지 모르기 때문에 사용자가 직접 Comparable 인터페이스를 implements해서 compareTo() 메서드에 클래스 정렬 기준을 명시해야 한다.

⇒ Collections.sort()의 내부 구조를 보면 인자로 받는 리스트의 요소들이 반드시 Comparable<>을 구현하고 있어야 한다고 정의되어 있다.




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

Comparator 인터페이스는 클래스에 정렬 기준을 고정시키지 않고 필요할 때마다 원하는 정렬 기준을 동적으로 적용할 수 있다. Comparator을 사용하면 다양한 방식으로 객체를 정렬할 수 있다.

public static void main(String[] args) {
	List<Student> list = new ArrayList<>();
	// 리스트 요소 추가(생략)
	
	Collections.sort(list, new Comparator<Student>() {
		@Override
		public int compare(Student o1, Student o2) {
  			if(o1.getMajor().equals(o2.getMajor())	
				return o2.getAge() - o1.getAge();    // 나이 내림차순 정렬
  			return o1.getMajor().compareTo(o2.getMarjo());
		}
	}
}

클래스에서 Comparable<>의 compareTo()를 오버라이딩 했는데 main에서 Comparator<>의 compare()을 다시 오버라이딩한 경우

⇒ compareTo() 메서드는 클래스 내부에 그대로 유지되지만, Collections.sort()의 두 번째 인자에 Comparator을 넘기면, 자바는 compareTo()를 무시하고 인자로 넘겨받은 compare()의 규칙을 최우선으로 적용함

  • Comparable<>의 compareTo() : 객체의 기본 정렬 기준 (하나만 설정 가능)

  • Comparator<>의 compare() : 객체의 특별 정렬 기준



return 방식

  • 숫자형(int) 비교 방식
@Override
public int compare(Student o1, Student o2) {
	return o1.getStudentNo() - getStudentNo();
}
@Override
public int compare(Student o1, Student o2) {
	return Integer.compare(o1.getStudentNo(), o2.getStudentNo());
}

⇒ o1.x - o2.x 방식을 사용하면 정수 오버플로우가 발생한 경우 다른 결과를 도출하기 때문에 Integer.compare() 방식이 안전하다



  • 문자열(String 비교 방식)
@Override
public int compare(Student o1, Student o2) {
	return o1.getName().compareTo(o.getName());
}

⇒ 문자열은 숫자 타입이 아니기 때문에 빼기 연산(-)이 불가능하다. 따라서 문자열끼리 비교하기 위해서는 compareTo() 메서드를 사용하면 된다. (기존에 클래스에서 오버라이딩 했던 compareTo() 메서드와는 별개의 Stirng 비교 메서드이다.)

https://velog.io/@faulty337/Java%EC%9D%98-Collection-%EC%A0%95%EB%A0%AC-%EB%B0%A9%EB%B2%95






참고)

🚀 더 세련된 최신 방식 (Java 8+)

  • 학번으로 정렬할 때
Collections.sort(list, Comparator.comparingInt(Student::getStudentNo));
  • 이름으로 정렬할 때
Collections.sort(list, Comparator.comparing(Student::getName));

이 방식은 내부적으로 알아서 Integer.compareString.compareTo를 호출해주기 때문에 실수할 확률이 줄어든다

0개의 댓글