filter 메서드는 프레디케이트를 인수로 받아 프레디케이트와 일치하는 모든 요소를 포함하는 스트림을 반환
List<Dish> dishes = menu.stream().filter(Dish::isVegetarian).collect(toList());
위 예시에서 프레디케이트(불리언을 반환하는 함수) isVegetarian을 참조해 필터 진행
distinct(hascode나 equals로 판별)로 필터링
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, dropWhile 지원
List<Dish> specialMenu = Arrays.asList(
new Dish("fruit"),true, 120, Dish.Type.OTHER),
new Dish("prawns"),false, 300, Dish.Type.FISH),
new Dish("rice"),true, 350, Dish.Type.OTHER),
new Dish("chicken"),false, 400, Dish.Type.MEAT),
new Dish("fries"),true, 530, Dish.Type.OTHER),
);
List<Dish> slicedMenu1 = specialMenu.stream().takeWhile(dish -> dish.getCalories()<320).collect(toList());
결과: 리스트 처음부터 320 칼로리가 적은 음식들만 반환(fruit, prawns)
List<Dish> slicedMenu2 = specialMenu.stream().dropWhile(dish -> dish.getCalories()<320).collect(toList());
결과: 프레디케이트가 거짓이 되면 그 지점에서 작업 중단 후 남은 요소 반환(rice, chickem, fries), 무한 스트림에서도 동작
limit(n) 메서드를 써서 n개의 요소를 반환할 수 있다
List<Dish> dishes = specialMenu.stream().filter(dish -> dish.getCalories()>300).limit(3).collect(toList());
결과: rich, chicken, fries 반환
skip(n)을 사용하면 해당 조건을 만족하는 스트림 값 n개를 건너 뛴 값을 반환
n보다 스트림 결과값이 작다면 빈 스트림을 반환
함수를 인수로 받는 map 메서드를 지원
List<String> dishNames = menu.stream().map(Dish::getName).collect(toList());
flatMap: 스트림의 각 값을 다른 스트림으로 만든 다음에 모든 스트림을 하나의 스트림으로 연결
모든 스트림 요소를 처리해 값으로 도출하는 작업
int sum = numbers.stream(reduce(0, (a,b) -> a + b);
reduce는 두가지 인수를 갖는다
reduce 객체에서 초깃값을 안받는 경우도 있는데 이 때는 빈 스트림일 수 있기 때문에 반환값이 Optional이 된다
마찬가지로 reduce 함수에 다음과 같이 넣어서 구할 수 있다
Optional<Integer> min = numbers.stream().reduce(Integer::min);
내부 반복이 추상화 되면서 내부 구현에서 병렬로 reduce를 실행할 수 있음(stream을 parallelStream()으로 바꾼다)
하지만 병렬로 실행이 되려면 reduce에서 넘겨준 람다의 상태가 바뀌지 말아야 하며, 연산이 어떤 순서로 실행되더라도 결과가 바뀌지 않는 구조여야 한다.
숫자 스트림을 효율적으로 처리할 수 있도록 기본 특화형 스트림을 제공
IntStream, DoubleStream, LongStream을 제공하는데 숫자 연산에서 사용하는 sum, max와 같은 메서드를 제공
mapToInt, mapToDouble, mapToLong을 많이 사용
int calories = menu.stream().mapToInt(Dish::getCalories).sum();
boxed 메서드를 사용해서 특화 되지 않은 일반 스트림으로 변환 가능
IntStream intStream = menu.stream().mapToInt(Dish::getCalories);
Stream<Integer> stream = intStream.boxed();
range(시작값과 종료값 포함), rangeClosed(시작값과 종료값 불포함)을 사용해 특정 범위 사이의 숫자들을 생성 가능
Stream.of을 이용해 스트림을 만들 수 있고 empty 메서드를 이용해 비울 수 있다.
Stream<String> stream = Stream.of("Hello", "World");
Stream<String> empty = Stream.empty();
Stream.ofNullable을 이용해 null 값이 될 수 있는 스트림 생성 가능
Stream<String> values = Stream.ofNullable(System.getProperty("home"));
Arrays.stream을 이용해 배열을 인수로 받아 스트림을 만드는 것이 가능
int[] num = {2,3,5,7};
int sum = Arrays.stream(num).sum();
파일을 처리하는 NIO API에서 스트림 API를 활용 가능
Files.lines로 파일의 각 행 요소를 반환하는 스트림을 얻는 것이 가능
Stream.iterate, Stream.generate으로 크기가 고정 되지 않은 스트림을 생성할 수 있다
하지만 보통 무한한 값을 출력하지 않도록 limit(n)과 함께 사용
limit을 사용하지 않는다면 최종 연산에서 아무 결과가 반환되지 않으며 무한적으로 계산이 반복되므로 정렬이나 리듀스할 수 없다.