CodeGym /행동 /JAVA 25 SELF /Java 컬렉션에서 요소 검색과 정렬

Java 컬렉션에서 요소 검색과 정렬

JAVA 25 SELF
레벨 29 , 레슨 4
사용 가능

1. 컬렉션에서 요소 검색

표준 메서드로 검색하기

예를 들어 이름 목록 같은 리스트가 있을 때:

List<String> names = List.of("Anna", "Boris", "Viktoriya", "Anna", "Dmitriy");

Java는 검색을 위한 편리한 메서드를 제공합니다:

  • contains(Object o) — 컬렉션에 원소가 존재하는지 확인합니다.
  • indexOf(Object o) — 요소가 처음 나타나는 인덱스를 반환합니다(없으면 -1).
  • lastIndexOf(Object o) — 요소가 마지막으로 나타나는 인덱스를 반환합니다(없으면 -1).

예시:

System.out.println(names.contains("Anna"));      // true
System.out.println(names.indexOf("Anna"));       // 0
System.out.println(names.lastIndexOf("Anna"));   // 3
System.out.println(names.contains("Sergey"));    // false

사실: Set 타입 컬렉션에는 indexOflastIndexOf가 없습니다 — Set에는 애초에 인덱스가 없고, 고유 값만 있습니다.

조건으로 검색하기

가끔은 특정 값이 아니라 어떤 조건을 만족하는 요소를 찾아야 합니다. 예를 들어 길이가 6자를 초과하는 첫 번째 이름을 찾는 경우. 일반적인 for 루프가 아주 잘 맞습니다. 적합한 요소를 찾는 즉시 break를 사용하세요.

List<String> names = List.of("Anna", "Boris", "Viktoriya", "Anna", "Dmitriy");

String found = null;
for (String name : names) {
    if (name.length() > 6) {
        found = name;
        break; // 첫 번째로 조건을 만족하는 값을 찾았으니 루프 종료
    }
}
System.out.println(found); // Viktoriya

최대값과 최소값 찾기

비교 가능한 요소(예: 숫자)로 이루어진 컬렉션에서는 Collections 클래스를 사용해 최대값과 최소값을 빠르게 찾을 수 있습니다.

List<Integer> numbers = List.of(10, 5, 20, 7, 20, 3);

int max = Collections.max(numbers); // 20
int min = Collections.min(numbers); // 3

System.out.println("최댓값: " + max);
System.out.println("최솟값: " + min);

중요: 요소는 비교 가능해야 합니다(Comparable을 구현). 그렇지 않으면 Comparator를 전달해야 합니다.

2. 컬렉션 정렬

기본 정렬

정렬은 변경 가능한 리스트(예: ArrayList, LinkedList)에서만 가능합니다. SetMap 타입 컬렉션은 직접적인 정렬을 지원하지 않습니다.

기본적으로 정렬은 “자연 순서”로 진행됩니다. 숫자는 오름차순, 문자열은 알파벳 순입니다.

List<Integer> numbers = new ArrayList<>(List.of(5, 1, 7, 3));
Collections.sort(numbers);
System.out.println(numbers); // [1, 3, 5, 7]

리스트의 sort 메서드로도 같은 작업을 할 수 있습니다:

List<Integer> numbers = new ArrayList<>(List.of(5, 1, 7, 3));
numbers.sort(null); // null은 '자연 순서'를 사용하라는 뜻
System.out.println(numbers); // [1, 3, 5, 7]

Comparator로 정렬

사용자 정의 규칙이 필요하다면 — 예를 들어 문자열을 길이 기준으로 정렬:

List<String> words = new ArrayList<>(List.of("kot", "slon", "mukha", "nosorog"));

words.sort(Comparator.comparingInt(String::length));
System.out.println(words); // [kot, mukha, slon, nosorog]

내림차순으로:

words.sort(Comparator.comparingInt(String::length).reversed());
System.out.println(words); // [nosorog, slon, mukha, kot]

예전 스타일 — Collections.sort 사용:

Collections.sort(words, Comparator.comparingInt(String::length));

3. 컬렉션별 정렬 특성

정렬은 리스트에만 적용

정렬 메서드(sort, Collections.sort)는 요소의 순서를 유지하는 컬렉션(예: List)에만 동작합니다. SetMap에는 이러한 메서드가 없습니다.

Set을 정렬하려는 시도:

Set<Integer> mySet = new HashSet<>(List.of(3, 1, 2));
Collections.sort(mySet); // 컴파일 오류: sort는 List를 요구합니다!

Set에서 정렬된 리스트가 필요하다면:

List<Integer> sortedFromSet = new ArrayList<>(mySet);
Collections.sort(sortedFromSet);
System.out.println(sortedFromSet); // [1, 2, 3]

Map 정렬: 키와 값 기준

Map을 직접 정렬할 수는 없지만, 다음처럼 할 수 있습니다:

  • “키-값” 쌍 리스트를 얻는다
  • 원하는 기준으로 그 리스트를 정렬한다
  • 필요하다면 새로운 Map을 만든다

예: 값 기준 정렬

Map<String, Integer> scores = Map.of(
    "Anna", 15,
    "Boris", 20,
    "Vika", 12
);

List<Map.Entry<String, Integer>> entries = new ArrayList<>(scores.entrySet());
entries.sort(Map.Entry.comparingByValue());

for (Map.Entry<String, Integer> entry : entries) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}
// Vika: 12
// Anna: 15
// Boris: 20

객체를 필드 기준으로 정렬

사용자 클래스를 하나 가정해 봅시다:

class User {
    String name;
    int age;
    User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

그리고 사용자 리스트:

List<User> users = new ArrayList<>(List.of(
    new User("Anna", 22),
    new User("Boris", 18),
    new User("Vika", 25)
));

나이 기준 정렬:

users.sort(Comparator.comparingInt(u -> u.age));
System.out.println(users); // [Boris (18), Anna (22), Vika (25)]

내림차순:

users.sort(Comparator.comparingInt((User u) -> u.age).reversed());
System.out.println(users); // [Vika (25), Anna (22), Boris (18)]

4. 컬렉션 검색/정렬 시 자주 하는 실수

오류 №1: 불변 리스트를 정렬하려 함. List.of(...)로 생성한 리스트는 변경할 수 없습니다 — sort를 호출하면 UnsupportedOperationException이 발생합니다.

List<Integer> immutable = List.of(3, 1, 2);
immutable.sort(null); // 예외를 던집니다!

오류 №2: Set 또는 Map을 직접 정렬하려 함. 정렬 메서드는 SetMap에는 동작하지 않습니다. 정렬이 필요하면 먼저 데이터를 리스트로 변환하세요.

오류 №3: 잘못된 객체 비교. 비교 시 정수를 그대로 빼지 마세요 — 오버플로가 발생할 수 있습니다. u1.age - u2.age 대신 Integer.compare 또는 Comparator.comparingInt을 사용하세요.

// users.sort((u1, u2) -> u1.age - u2.age); // 작동은 하지만 오버플로 위험이 있습니다!

오류 №4: 복잡한 검색에 contains 사용. containsequals를 기준으로 한 완전 일치만 확인합니다. 문자열의 일부나 객체의 특정 필드로 검색하려면 조건 검사를 포함한 루프 또는 Comparator/스트림을 사용하세요.

1
설문조사/퀴즈
컴퍼레이터와 객체 비교, 레벨 29, 레슨 4
사용 불가능
컴퍼레이터와 객체 비교
컴퍼레이터와 객체 비교
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION