Ch14-26~29. 스트림 중간연산
0. 목차
Chapter14. 람다와 스트림
Ch14 - 26. 스트림의 중간연산 : skip(), limit()
Ch14 - 27. 스트림의 중간연산 : filter(), distinct()
Ch14 - 28. 스트림의 중간연산 : sorted()
Ch14 - 29. 스트림의 중간연산 : Comparator의 메서드
Ch14 - 26. 스트림의 중간연산 : skip(), limit()
▶ skip()
▷ 앞에서부터 n개 건너뛰기
Stream<T> skip(long n)
▶ limit()
▷ maxSize 이후의 요소부터는 자르기
Stream<T> limit(long maxSize)
▶ 예시
▷ skip(), limit()
IntStream intStream = IntStream.rangeClosed(1, 10); // 12345678910
intStream
.skip(3) // 123 -3칸 건너뛰고 시작→ 45678910
.limit(5) // 45678-여기서 부터 뒤는 LIMIT!→ 910
.forEach(System.out::print);
Ch14 - 27. 스트림의 중간연산 : filter(), distinct()
▶ filter()
▷ 조건식을 주고, 조건에 맞지 않는 요소 제거
Stream<T> filter(Predicate<? super T> predicate)
▶ distinct()
▷ 중복 제거
Stream<T> distinct()
▶ 예시
▷ distinct()
IntStream intStream = IntStream.of(1, 2, 2, 3, 3, 4, 5, 5, 6,); // 123456
intStream
.distinct()
.forEach(System.out::print); // 중복 제거 후 123456 출력
▷ filter()
IntStream intStream = IntStream.rangeClosed(1, 10); // 12345678910
intStream
.filter(i -> i % 2 == 0) // 2의 배수!
.forEach(System.out::print); // 246810
filter()
는 중간 연산이므로 반복 가능
IntStream intStream = IntStream.rangeClosed(1, 10); // 12345678910 intStream .filter(i -> i % 2! == 0) // 2의 배수가 아니다!, 12345678910 → 13579 .filter(i -> i % 3! == 0) // 3의 배수가 아니다!, 13579 → 157 .forEach(System.out::print); // 157 // && 사용하여 한 줄로 작성 가능 filter(i -> i % 2! == 0 && i -> i % 3! == 0)
Ch14 - 28. 스트림의 중간연산 : sorted()
▶ sorted()
▷ 스트림 요소의 기본 정렬(Comparable)로 정렬
▷ 정렬에 필요한 정렬기준을 주지 않으면 기본 정렬 적용
Stream<T> sorted()
▷ 지정 된 Comparator로 정렬
Stream<T> sorted(Comparator<? super T> comparator)
▶ 문자열 스트림 정렬 방법
▷ 출력 결과
CCaaabcdd
sorted()
▷ strStream.sorted() // 기본 정렬 ▷ strStream.sorted(Comparator.naturalOrder()) // 기본 정렬 ▷ strStream.sorted((s1, s2) -> s1.compareTo(s2)); // 람다식 가능 ▷ strStream.sorted(String::compareTo); // 위의 람다식을 메서드 참조로 변경
▷ 출력 결과
ddccbaaaCC
sorted()
▷ strStream.sorted(Comparator.reverseOrder()) // 기본 정렬의 역순 ▷ strStream.sorted(Comparator.<String>naturalOrder().reversed())
▷ 출력 결과
aaabCCccdd
sorted()
▷ strStream.sorted(String.CASE_INSENSITIVE_ORDER) // 대소문자 구분 안함
- String.CASE_INSENSITIVE_ORDER
// String 클래스가 Comparator를 만들어 두고 사용하라고 준 아이템(?) 같은 거 statioc Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsenstiveComparator();
- String.CASE_INSENSITIVE_ORDER
▷ 출력 결과
ddCCccbaaa
sorted()
▷ strStream.sorted(String.CASE_INSENSITIVE_ORDER.reversed()) // 대소문자 구분 안함의 역순
▷ 출력 결과
bddCCccaaa
sorted()
▷ strStream.sorted(Comparator.comparing(String::length)) // 길이 순 정렬 ▷ strStream.sorted(Comparator.comparingInt(String::length)) // 오토박싱 안함
▷ 출력 결과
aaaddCCccb
sorted()
▷ strStream.sorted(Comparator.comparing(String::length).reversed()) // 길이 순 정렬의 역순
Ch14 - 29. 스트림의 중간연산 : Comparator의 메서드
▶ Comparator의 메서드 : comparing()
▷ comparing()으로 정렬 기준 제공
comparing(Function<T, U> keyExtractor)
comparing(Function<T, U> keyExtractor, Comparator<U> keyComparator)
▷ 예시
// 반별로 정렬
studentStream
.sorted(Comparator.comparing Student::getBan)
.forEach(System.out::println);
▶ Comparator의 메서드 : thenComparing()
▷ thenComparing()으로 추가 정렬 기준 제공
thenComparing(Comparator<T> other)
thenComparing(Function<T> keyExtractor)
thenComparing(Function<T, U> keyExtractor, Comparator<U> keyComp)
▷ 예시
studentStream
.sorted(Comparator.comparing Student::getBan) // 반별로 정렬
.thenComparing(Student::getTotalScore) // 총점 별로 정렬
.thenComparing(Student::getName) // 이름 별로 정렬
.forEach(System.out::println);
▶ 실습
▷ Stream 생성
Stream<Student> studentStream = Stream.of(
new Student("이자바", 3, 300),
new Student("김자바", 1, 200),
new Student("안자바", 2, 100),
new Student("박자바", 2, 150),
new Student("소자바", 1, 200),
new Student("나자바", 3, 290),
new Student("감자바", 3, 180)
);
▷ 반별 정렬, 기본 정렬
studentStream.sorted(Comparator.comparing(Student::getBan) // 반별 정렬
.thenComparing(Comparator.naturalOrder())) // 기본 정렬
.forEach(System.out::println);
▷ Student 클래스 : 이름, 반, 성적
String name;
int ban;
int totalScore;
Student(String name, int ban, int totalScore) {
this.name = name;
this.ban = ban;
this.totalScore = totalScore;
}
▷ Student 클래스 : toString()
public String toString() {
return String.format("[%s, %d, %d]", name, ban, totalScore);
}
▷ Student 클래스 : get()
String getName() { return name; }
int getBan() { return ban; }
int getTotalScore() { return totalScore; }
▷ Student 클래스 : compareTo()
// 총점 내림차순을 기본 정렬로 작성
public int compareTo(Student s) {
return s.totalScore - this.totalScore;
}
▷ 전체
import java.util.*;
import java.util.stream.*;
class Ex14_5 {
public static void main(String[] args) {
Stream<Student> studentStream = Stream.of(
new Student("이자바", 3, 300),
new Student("김자바", 1, 200),
new Student("안자바", 2, 100),
new Student("박자바", 2, 150),
new Student("소자바", 1, 200),
new Student("나자바", 3, 290),
new Student("감자바", 3, 180)
);
studentStream.sorted(Comparator.comparing(Student::getBan) // 반별 정렬
.thenComparing(Comparator.naturalOrder())) // 기본 정렬
.forEach(System.out::println);
}
}
class Student implements Comparable<Student> {
String name;
int ban;
int totalScore;
Student(String name, int ban, int totalScore) {
this.name = name;
this.ban = ban;
this.totalScore =totalScore;
}
public String toString() {
return String.format("[%s, %d, %d]", name, ban, totalScore);
}
String getName() { return name; }
int getBan() { return ban; }
int getTotalScore() { return totalScore; }
// 총점 내림차순을 기본 정렬 작성
public int compareTo(Student s) {
return s.totalScore - this.totalScore;
}
}
// console
[김자바, 1, 200]
[소자바, 1, 200]
[박자바, 2, 150]
[안자바, 2, 100]
[이자바, 3, 300]
[나자바, 3, 290]
[감자바, 3, 180]