Java 컬렉션 정렬, Collections.sort와 Comparator 완벽 가이드
📌 자바 List 정렬을 손쉽게! 실무에서 자주 쓰는 Collections.sort 사용법
Java 개발을 하다 보면 데이터의 정렬은 꼭 필요한 기능 중 하나입니다.
특히 리스트(List) 형태의 데이터를 특정 기준에 맞춰 오름차순이나 내림차순으로 정렬하는 작업은 매우 빈번하게 발생하죠.
하지만 Collections.sort() 메서드를 어떻게 사용해야 할지, Comparator 인터페이스는 왜 필요한지 헷갈리는 분들도 많습니다.
오늘은 그런 분들을 위해 Java 컬렉션 정렬의 핵심을 쉽게 풀어드릴게요.
차근차근 따라오시면 실무에서도 바로 적용 가능한 수준까지 이해할 수 있습니다.
이번 글에서는 Java 컬렉션 프레임워크 중 List 인터페이스를 기반으로, 정렬을 위한 핵심 메서드인 Collections.sort()와 정렬 기준을 정의하는 Comparator 구현 방법까지 자세히 설명드릴 예정입니다.
또한 자바의 예외 처리 흐름도 함께 다루어, 안정적인 코드 작성을 위한 팁도 함께 알려드릴게요.
초보자도 이해할 수 있도록 다양한 코드 예제와 함께 설명드리니 끝까지 읽어보시면 분명 도움이 되실 거예요.
📋 목차
📌 Java 예외 처리와 컬렉션의 관계
Java에서 예외 처리는 프로그램 실행 중 발생할 수 있는 오류 상황을 처리하기 위한 구조입니다.
특히 컬렉션 프레임워크를 사용할 때는 다양한 예외가 발생할 수 있기 때문에 적절한 예외 처리가 중요합니다.
예를 들어, 리스트의 인덱스를 잘못 지정하면 IndexOutOfBoundsException이 발생하며, null 객체를 정렬할 경우에는 NullPointerException이 발생할 수 있습니다.
따라서 컬렉션을 다룰 때는 예외 상황을 미리 예측하고 적절히 처리하는 것이 필수입니다.
정렬을 수행할 때도 마찬가지로, 데이터가 null일 가능성이 있다면 정렬 전에 미리 필터링하거나 예외 처리를 통해 오류를 방지해야 합니다.
🧩 자주 발생하는 예외 사례
- 📛NullPointerException: 정렬 대상 리스트에 null 요소가 있을 경우
- 🔢IndexOutOfBoundsException: 존재하지 않는 인덱스에 접근할 경우
- ❌ClassCastException: 서로 다른 타입의 객체를 비교할 경우
✅ 예외 방지를 위한 팁
정렬 전에 null 값이 포함된 데이터를 제거하거나, null-safe 비교를 제공하는 Comparator를 사용하면 예외를 방지할 수 있습니다.
또한, 리스트가 비어 있거나 null인 경우를 대비해 아래와 같은 코드 패턴을 활용하는 것이 좋습니다.
if (list != null && !list.isEmpty()) {
Collections.sort(list);
}
예외 처리는 단순히 오류를 피하기 위한 수단이 아니라, 프로그램의 신뢰성을 높이는 중요한 요소입니다.
컬렉션을 다루는 모든 과정에서 예외 처리를 염두에 두는 습관을 들이세요.
📌 컬렉션 프레임워크 핵심 구조 이해
Java 컬렉션 프레임워크는 데이터를 효율적으로 저장하고 처리하기 위한 구조화된 클래스들의 집합입니다.
여기에는 List, Set, Queue, Map 등의 인터페이스와 이를 구현한 다양한 클래스들이 포함됩니다.
이 프레임워크를 활용하면 배열보다 더 유연하게 데이터를 추가, 삭제, 정렬할 수 있으며, 실무에서도 거의 모든 Java 애플리케이션에서 사용됩니다.
특히 정렬 작업은 List 계열에서 자주 발생하며, 프레임워크의 구조를 이해하면 성능과 유지보수 측면에서 더 나은 코드를 작성할 수 있습니다.
📂 컬렉션 인터페이스 계층 구조
컬렉션 프레임워크는 다음과 같은 계층 구조로 이루어져 있습니다.
| 인터페이스 | 설명 |
|---|---|
| Collection | 모든 컬렉션 클래스의 최상위 인터페이스 |
| List | 순서가 있는 데이터 집합, 중복 허용 |
| Set | 중복을 허용하지 않는 집합 |
| Queue | FIFO(선입선출) 구조를 따르는 인터페이스 |
| Map | 키-값 쌍으로 구성된 데이터 구조 (Collection 아님) |
💡 TIP: 어떤 컬렉션을 써야 할까?
💡 TIP: 데이터의 중복 여부와 순서 유지를 고려하여 컬렉션을 선택하세요.
중복 허용 + 순서 중요 → List,
중복 불허 + 순서 무관 → Set,
키-값 저장 → Map을 선택하면 됩니다.
정렬 기능은 주로 List 인터페이스에서 사용되며, 그 핵심 기능이 바로 다음 섹션에서 다룰 Collections.sort()입니다.
List를 이해하고 있어야 정렬 메서드도 쉽게 사용할 수 있답니다.
📌 List 인터페이스의 특징과 용도
Java에서 List 인터페이스는 순서가 있는 데이터 집합을 표현하는 데 사용됩니다.
데이터가 삽입된 순서를 유지하며, 중복된 값을 허용한다는 점이 가장 큰 특징입니다.
실무에서 사용자 목록, 게시글 리스트, 상품 카탈로그 등 다양한 곳에 활용되며, 정렬과 검색이 필요한 상황에 자주 사용됩니다.
List는 ArrayList, LinkedList, Vector 등 다양한 구현 클래스를 통해 사용되며, 상황에 따라 적합한 클래스를 선택할 수 있습니다.
📌 주요 메서드와 활용법
List는 다음과 같은 주요 메서드를 통해 데이터를 조작합니다.
- ➕add(E e) – 요소 추가
- 🗑️remove(int index) – 인덱스로 요소 제거
- 🔄set(int index, E element) – 특정 위치 요소 수정
- 🔍get(int index) – 인덱스로 요소 조회
💎 핵심 포인트:
💎 핵심 포인트:
List는 정렬이 필요한 데이터를 담는 데 가장 많이 사용되는 컬렉션입니다.
Collections.sort()는 List 타입을 정렬하기 위한 전용 메서드이기 때문에, 정렬 전에는 반드시 데이터를 List로 구성해야 합니다.
이제 List 인터페이스의 구조와 특징을 잘 이해하셨다면, 본격적으로 Collections.sort() 메서드로 정렬을 수행하는 방법을 알아볼 차례입니다.
📌 Collections.sort() 기본 사용법
Java에서는 List 컬렉션을 정렬할 때 Collections.sort() 메서드를 가장 많이 사용합니다.
이 메서드는 java.util 패키지에 포함되어 있으며, 내부적으로 TimSort 알고리즘을 사용해 안정적이고 빠른 정렬을 제공합니다.
기본적으로 요소가 Comparable 인터페이스를 구현하고 있어야만 사용할 수 있습니다.
🔰 기본 정렬 예제
import java.util.*;
public class SortExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(5, 1, 4, 2, 3);
Collections.sort(numbers);
System.out.println(numbers); // [1, 2, 3, 4, 5]
}
}
이처럼 기본 타입(Integer, String 등)은 이미 Comparable 인터페이스를 구현하고 있어 바로 정렬이 가능합니다.
⚠️ 사용자 정의 클래스 정렬 주의
⚠️ 주의: 사용자 정의 클래스는 Comparable 또는 Comparator 인터페이스를 직접 구현하지 않으면 Collections.sort()를 사용할 수 없습니다.
예를 들어, 다음과 같은 클래스가 있다고 가정해볼게요.
class Product {
String name;
int price;
Product(String name, int price) {
this.name = name;
this.price = price;
}
}
이 경우에는 정렬을 위해 Comparator를 따로 구현해주거나, Comparable을 직접 구현해야 합니다.
이러한 사용자 지정 정렬은 다음 STEP에서 자세히 설명드릴게요.
📌 Comparator 인터페이스로 정렬 커스터마이징
사용자 정의 객체를 정렬하려면 Comparator 인터페이스를 구현하거나, 람다식 혹은 익명 클래스 방식으로 정렬 기준을 지정해줘야 합니다.
Collections.sort는 Comparator를 두 번째 인자로 받아 정렬 기준을 유연하게 설정할 수 있습니다.
🧠 Comparator 사용 예제
import java.util.*;
class Product {
String name;
int price;
Product(String name, int price) {
this.name = name;
this.price = price;
}
public String toString() {
return name + " (" + price + ")";
}
}
public class CustomSortExample {
public static void main(String[] args) {
List<Product> products = Arrays.asList(
new Product("노트북", 1500),
new Product("태블릿", 900),
new Product("스마트폰", 1200)
);
// 가격 기준 오름차순 정렬
Collections.sort(products, new Comparator<Product>() {
public int compare(Product p1, Product p2) {
return Integer.compare(p1.price, p2.price);
}
});
System.out.println(products);
}
}
Comparator는 매우 유연한 구조로, 여러 기준으로도 정렬이 가능합니다.
예를 들어 이름을 기준으로 정렬하거나, 가격의 내림차순으로 바꿀 수도 있죠.
🚀 람다 표현식으로 더 간단하게
Java 8 이상에서는 람다식을 사용해 더욱 간결하게 Comparator를 정의할 수 있습니다.
Collections.sort(products, (p1, p2) -> p1.price - p2.price);
이처럼 Comparator는 Java의 정렬 기능을 강력하게 만들어주는 도구입니다.
정렬 기준이 복잡할수록 Comparator를 적절히 활용하는 것이 좋은 코드 품질로 이어집니다.
❓ 자주 묻는 질문 (FAQ)
Collections.sort()는 어떤 알고리즘을 사용하나요?
List와 Array는 무엇이 다른가요?
Comparator와 Comparable은 무엇이 다른가요?
Collections.sort()는 어떤 컬렉션에만 사용할 수 있나요?
정렬 시 null 값을 포함하면 어떻게 되나요?
람다식은 어떤 버전부터 사용할 수 있나요?
정렬 기준을 여러 개 지정할 수 있나요?
정렬 성능을 개선할 수 있는 팁이 있나요?
🧩 Java List 정렬, 제대로 이해하면 실력이 됩니다
Java에서 데이터 정렬은 단순한 출력 이상의 의미를 갖습니다.
실제 애플리케이션에서는 사용자 경험을 높이기 위한 필수 기능이며, 개발자의 기초 역량을 평가하는 지표가 되기도 하죠.
이번 글에서는 Java 컬렉션 프레임워크 중 List 인터페이스를 중심으로 Collections.sort() 메서드와 Comparator 인터페이스의 사용법을 실전 예제와 함께 자세히 살펴보았습니다.
기본 타입 정렬에서 사용자 정의 객체까지, 그리고 예외 처리와 정렬 기준 커스터마이징까지 단계별로 이해했다면, 이제는 실무에서 자신 있게 적용하실 수 있을 거예요.
정렬은 생각보다 자주 등장하는 문제이니 꼭 한 번 실습해보고, 람다식과 다양한 비교 전략도 익혀보시길 추천드립니다.
꾸준한 연습이 곧 실력입니다.
🏷️ 관련 태그 : Java, 컬렉션프레임워크, List인터페이스, Collections.sort, Comparator, Java정렬, 람다식정렬, 자바기초, 예외처리, 개발자팁