본문 바로가기
Web Programming Language/JAVA

스트림(Stream) 활용 - 요소 정렬, 루핑(유소 개별 처리), 매칭(조건 만족 여부)

by manchesterandthecity 2025. 3. 6.

자바의 스트림(Stream) API는 데이터를 다룰 때 효율적이고 간결한 처리를 가능하게 합니다. 이번 글에서는 스트림 요소 정렬, 요소를 하나씩 처리하는 루핑, 요소의 조건 만족 여부 검사에 대해 살펴보겠습니다.


🔹 1. 요소 정렬 (Sorting)

스트림에서 요소를 정렬하려면 sorted() 메소드를 사용합니다.

📌 sorted() 메소드 종류

메소드 설명
sorted() 요소가 Comparable을 구현한 경우 자동 정렬
sorted(Comparator<T> comparator) Comparator를 사용하여 맞춤형 정렬

📌 예제 1: 기본 정렬 (Comparable이 구현된 경우)

List<String> names = List.of("Java", "Python", "C++", "Kotlin");

names.stream()
     .sorted() // 알파벳순 정렬
     .forEach(System.out::println);

// 결과:
// C++
// Java
// Kotlin
// Python
  • String 클래스는 Comparable을 구현하고 있어 sorted()만 호출해도 정렬됩니다.

📌 예제 2: Comparator를 사용한 정렬 (내림차순)

List<String> names = List.of("Java", "Python", "C++", "Kotlin");

names.stream()
     .sorted(Comparator.reverseOrder()) // 내림차순 정렬
     .forEach(System.out::println);

// 결과:
// Python
// Kotlin
// Java
// C++

📌 예제 3: 객체 정렬 (Comparable 구현)

객체가 Comparable을 구현하면 sorted()로 정렬할 수 있습니다.

class Student implements Comparable<Student> {
    String name;
    int score;
    
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public int compareTo(Student other) {
        return Integer.compare(this.score, other.score); // 점수 오름차순 정렬
    }
}

List<Student> students = List.of(
    new Student("홍길동", 85),
    new Student("이순신", 90),
    new Student("강감찬", 80)
);

students.stream()
        .sorted() // 점수 오름차순 정렬
        .forEach(s -> System.out.println(s.name + ": " + s.score));

// 결과:
// 강감찬: 80
// 홍길동: 85
// 이순신: 90

📌 예제 4: Comparator를 사용한 정렬

객체가 Comparable을 구현하지 않아도 Comparator를 직접 제공하면 정렬이 가능합니다.

students.stream()
        .sorted(Comparator.comparingInt(s -> s.score)) // 점수 오름차순 정렬
        .forEach(s -> System.out.println(s.name + ": " + s.score));

// 내림차순 정렬
students.stream()
        .sorted((s1, s2) -> Integer.compare(s2.score, s1.score))
        .forEach(s -> System.out.println(s.name + ": " + s.score));

 


🔹 2. 요소를 하나씩 처리 (루핑)

스트림에서 요소를 하나씩 처리하는 방법은 크게 두 가지입니다.

📌 forEach() vs peek()

메소드 설명
forEach(Consumer<T>) 최종 처리 메소드 (출력, 저장 등 최종 작업)
peek(Consumer<T>) 중간 처리 메소드 (디버깅, 중간 확인 용도)

📌 예제 1: forEach() - 최종 처리

List<String> names = List.of("Java", "Python", "C++", "Kotlin");

names.stream()
     .forEach(System.out::println); // 요소 하나씩 출력
  • forEach()는 최종 처리 메소드이므로 스트림이 끝납니다.

📌 예제 2: peek() - 중간 처리 (디버깅 용도)

List<String> names = List.of("Java", "Python", "C++", "Kotlin");

names.stream()
     .peek(name -> System.out.println("처리 전: " + name)) // 중간 출력
     .sorted()
     .forEach(name -> System.out.println("처리 후: " + name));
  • peek()은 스트림 요소를 변환하지 않고 중간 상태를 확인하는 데 사용됩니다.
  • 반드시 forEach() 같은 최종 처리 메소드가 뒤에 와야 동작합니다.

📌 예제 3: peek() 활용 (짝수 필터링 후 합산)

int sum = IntStream.of(1, 2, 3, 4, 5)
                   .filter(n -> n % 2 == 0) // 짝수 필터링
                   .peek(n -> System.out.println("필터링된 값: " + n))
                   .sum(); // 최종 연산

// 결과:
// 필터링된 값: 2
// 필터링된 값: 4
// sum = 6

 


🔹 3. 요소 조건 만족 여부 (매칭)

스트림의 모든 요소가 특정 조건을 만족하는지 확인하는 기능입니다.

📌 매칭 메소드 종류

메소드 설명
allMatch(Predicate<T>) 모든 요소가 조건을 만족하는지 검사
anyMatch(Predicate<T>) 하나라도 조건을 만족하는 요소가 있는지 검사
noneMatch(Predicate<T>) 모든 요소가 조건을 만족하지 않는지 검사

📌 예제 1: allMatch() - 모든 요소가 조건을 만족하는지 검사

boolean allEven = IntStream.of(2, 4, 6, 8, 10)
                           .allMatch(n -> n % 2 == 0); // 모든 요소가 짝수인가?

System.out.println(allEven); // true

📌 예제 2: anyMatch() - 하나라도 조건을 만족하는 요소가 있는지 검사

boolean hasOdd = IntStream.of(2, 4, 6, 7, 10)
                          .anyMatch(n -> n % 2 != 0); // 홀수가 하나라도 있는가?

System.out.println(hasOdd); // true

📌 예제 3: noneMatch() - 모든 요소가 조건을 만족하지 않는지 검사

boolean noNegative = IntStream.of(2, 4, 6, 8, 10)
                              .noneMatch(n -> n < 0); // 음수가 없는가?

System.out.println(noNegative); // true

🎯 정리

기능 메소드 설명
정렬 sorted() 기본 정렬 (Comparable 필요)
sorted(Comparator<T>) 커스텀 정렬
요소 개별 처리 forEach() 최종 처리 (출력, 저장 등)
peek() 중간 처리 (디버깅, 확인 용도)
조건 검사 allMatch(Predicate<T>) 모든 요소가 조건을 만족하는지 확인
anyMatch(Predicate<T>) 하나라도 조건을 만족하는지 확인
noneMatch(Predicate<T>) 모든 요소가 조건을 만족하지 않는지 확인

 

스트림을 활용하면 데이터를 보다 효율적으로 정렬하고, 개별 요소를 처리하고, 조건을 검사할 수 있습니다. 이를 잘 활용하면 복잡한 루프를 최소화하면서도 가독성이 좋은 코드를 작성할 수 있습니다. 🚀

 

 

 

 

 

 

참조:
이것이 자바다 _ 신용권

 

 

 

댓글