
스트림의 요소를 선택하는 방법에 대해 배움
filter 메서드
List<Dish> vegetarianMenu = menu.stream().filter(Dish::isVegetarian).collect(toList());
고유 요소로 이루어진 스트림을 반환하는 distinct 메서드도 지원
고유 결정 여부
ex) 리스트의 모든 짝수를 선택하고 중복을 필터링
List<Integer> numbers = Arrays.asList(1,2,1,3,3,2,4);
numbers.stream()
.filter(i -> i%2 ==0)
.distinct()
.forEach(System.out::println)
TakeWhile 활용
List<Dish> filteredMenu = specialMenu.stream()
.filter(dish -> dish.getCalories()< 320)
.collect(toList());
→ 리스트가 이미 정렬되어 있다는 사실을 이용해 320 칼로리보다 크거나 같은 요리가 나왔을 때 반복 작업을 중단 할 수 있음
→ takeWhile 이용하면 무한 스트림을 포함한 모든 스트림에 프레디케이트를 적용해 스트림 슬라이스 가능
List<Dish> sliceMenu1 = specialMenu.stream()
.takeWhile(dish -> dish.getCalories <320)
.collect(toList());
DROPWHILE 활용
나머지 요소를 선택하려면?
→dropWhile 사용
List<Dish> sliceMenu2 = specialMenu.stream()
.dropWhile(dish -> dish.getCalories() <320)
.collect(toList());
스트림
List<Dish> dishes = specialMenu.stream()
.filter(dish -> dish.getCalories() > 300)
.limit(3)
.collect(toList());
스트림
ex) 300 칼로리 이상의 처음 두 요리를 건너뛴 다음에 300 칼로리가 넘는 나머지 요리를 반환
List<Dish> dishes = menu.stream()
.filter(d ->< d.getCalories() > 300)
.skip(2)
.collect(toList());
스트림
ex) Dish::getName을 map 메서드로 전달해 스트림의 요리명 추출
List<String> dishNames = menu.stream()
.map(Dish::getName)
.collect(toList());
getName
→ map 메서드 출력 스트림 Strem 형식
고유 문자로 이루어진 리스트를 반환
ex) [”Hello”] → [”H”,”e”,”l”,”o”]
words.stream()
.map(word -> word.split("")
.distint()
.collect(toList());
→ 반환 형식이 문제
map 과 Arrays.Stream 활용
→ 안됨 스트림 리스트가 만들어지면서 문제 해결이 안됨
flatMap 사용
List<String> uniqueCharacters= words.stream()
.map(word -> word.split(""))
.flatMap(Arrays::stream)
.distinct()
.collect(toList());
flatMap
→ 세 메서드는 스트림 쇼트서킷 기법 , 즉 자바의 &&, || 와 같은 연산
Optional<Dish> dish = menu.stream().filter(Dish::isVegetarian).findAny();
Optional이란?
Optional
리듀스 연산 이용
reduce를 이용해서 스트림의 모든 요소를 더할 수 있음
int sum = numbers.stream().reduce(0,(a,b) -> a+b);
메서드 참조 이용하면 더 간결
int sum = numbers.stream().reduce(0,Integer::sum);
초깃값 없음
Optional<Integer> sum = numbers.stream().reduce((a,b) -> (a+b));
두 인수를 받음
두 요소에서 최댓값을 반환하는 람다만 있으면 구할 수 있음
→ reduce 연산은 새로운 값을 이용해서 스트림의 모든 요소를 소비할 때까지 람다를 반복수행해서 최댓값 생산
Optional<Integer> max = numbers.stream().reduce(Integer::max);
알아서 다른곳에 풀겠다.
스트림 API
특화스트림
숫자 스트림으로 매핑
int calories = menu.stream() // Stream<Dish> 반환
.mapToInt(Dish::getCalories) //IntStream 반환
.sum();
객체 스트림으로 복원하기
기본값: OptionalInt
스트림에 요소가 없는 상화과 실제 최댓값이 0인 상황 구별 법
ex) 1에서 100 사이의 숫자를 생성 가정
IntStream evenNumbers= IntStream.rangeClosed(1,100)
//[1,100]의 범위를 나타냄
수학이 자꾸 나오네;;
세수 표현하기
좋은 필터링 조합
집합 생성
필터를 이용해 좋은 조합을 갖는 a,b를 선택
세번 째 수 찾는 법
stream.filter( b →Math.sqrt(a*a + b*b) % 1 == 0)
.map(b -> new int[]{a,b,(int) Math.sqrt(a*a*+b*b)});
b값 생성
Intstream.rangeClosed(1,100)
.filter( b →Math.sqrt(a*a + b*b) % 1 == 0)
.boxed()
.map(b -> new int[]{a,b,(int) Math.sqrt(a*a*+b*b)});
a 값 생성
Stream<intp[> pythagoreanTriples = IntStream.rangeClosed(1,100).boxed()
.flatMap( a-> IntStream.rangeClosed(a,100)
.filter(b -> Math.sqrt(a*a +b*b) % 1 == 0)
.mapToObj(b -> new int[]{a,b,(int)Math.sqrt(a*a+bb*b)}))
→ 무제한 값 계산 가능 하지만 보통 limit(n) 함수를 사용해 연결
iterate 메서드
Stream.iterate(0,n->n+2)
.limit(10)
.forEach(System.out::println);
generate 메서드
//1번
List<Transcation> allTranscation = transactions.stream()
.filter(transaction-> transaction.getYear() ==2011)
.sorted(comparing(Transcation::getValue))
.collect(toList())
//2번
List<Transcation> allCity = transactions.stream()
.map(transaction ->transaction.getTrader().getCity())
.distinct()
.collect(toList());
List<Trader> allCam = transactions.stream()
.map(Transcation::getTrader)
.filter(trader -> trader.getCity().equals("Cambridge"))
.distinct()
.sorted(comparing(Trader::getName))
.collect(toList());