자바의 스트림(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>) | 모든 요소가 조건을 만족하지 않는지 확인 |
스트림을 활용하면 데이터를 보다 효율적으로 정렬하고, 개별 요소를 처리하고, 조건을 검사할 수 있습니다. 이를 잘 활용하면 복잡한 루프를 최소화하면서도 가독성이 좋은 코드를 작성할 수 있습니다. 🚀
참조:
이것이 자바다 _ 신용권
'Web Programming Language > JAVA' 카테고리의 다른 글
스트림(Stream) 활용 - 요소 병렬 처리(Parallel Processing) (0) | 2025.03.06 |
---|---|
스트림(Stream) 활용 - 요소 정렬, 루핑(유소 개별 처리), 매칭(조건 만족 여부) (0) | 2025.03.06 |
스트림(Stream) 활용 - 리소스로부터 스트림 얻기, 요소 걸러내기(필터링), 요소 변환(매핑) (0) | 2025.03.06 |
스트림(Stream) - 스트림, 내부 반복자, 중간 처리와 최종 처리 (0) | 2025.03.06 |
람다식(Lambda Expression) - 메소드 참조, 생성자 참조 (1) | 2025.03.05 |
댓글