이 글은 모던 자바 인 액션 책을 읽고 정리한 내용입니다.
http://www.yes24.com/Product/Goods/77125987
1. 리듀싱
1.1. 요소의 합
리스트의 숫자 요소를 더하는 코드를 생각해보자.
리스트에서 하나의 숫자가 남을 때 까지 reduce 과정을 반복한다. 이런 상황에서 reduce를 이용하면 다음처럼 스트림의 모든 요소를 더할 수 있다.
<code />
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
자바 8에서는 Integer 클래스에 두 숫자를 더하는 정적 sum 메서드를 제공하기 때문에 직접 람다 코드를 구현할 필요가 없다.
<code />
int sum = numbers.stream().reduce(0, Integer::sum);
1.2. 최댓값과 최솟값
최댓값과 최솟값을 찾을 때도 reduce를 활용할 수 있다.
<code />
Optional<Integer> max = numbers.stream().reduce(Integer::max);
Optional<Integer> min = numbers.stream().reduce(Integer::min);
2. 기본형 특화 스트림
2.1. 숫자 스트림으로 매핑
스트림을 특화 스트림으로 변환할 때는 mapToInt, mapToDouble, mapToLong 이 세 가지 메서드를 가장 많이 사용한다.
<java />
int calories = menu.stream()
.mapToInt(Dish::getCalories) //IntStream 반환
.sum();
IntStream은 max, min, average 등 다양한 유틸리티 메서드도 지원한다.
2.2. 객체 스트림으로 복원하기
특화 스트림을 만든 뒤에 원 상태로 복원 할 수 있을까? 우리가 갖고 싶은게 숫자가 아닌 Dish 같은 다른 값을 받고 싶다면 ?
그럼 스트림 인터페이스에 정의된 일반적인 연산을 사용해야한다. 다음 예제처럼 boxed
메서드를 이용하여 다시 복원하자.
<code />
IntStream intStream = menu.stream().mapToInt(Dish::getCalories);
Stream<Integer> stream = intStream.boxed();
2.3. 숫자 범위
특정 범위의 숫자를 이용해야 할 때 range
와 rangeClosed
메서드를 사용할 수 있다. 이는 IntStream
, LongStream
두 기본형 특화 스트림에서 지원된다. range
는 경계값이 결과에 포함되지 않으며, rangeClosed
는 경계값을 결과에 포함된다.
3. 스트림 만들기
우리가 배웠던 방식 외에 다양한 방식으로도 스트림을 만들 수 있다.
3.1. 값으로 스트림 만들기
정적 메서드 Stream.of을 이용하여 스트림을 만들 수 있다.
<code />
Stream<String> stream = Stream.of("jiny","choi","samuel");
stream.map(String::toUpperCase).forEach(System.out::println);
//스트림 비우기
Stream<String> emptyStream = Stream.empty();
3.2. null이 될 수 있는 객체로 스트림 만들기
Stream.ofNullable 메서드를 이용하여 null이 될 수 있는 객체를 지원하는 스트림을 만들 수 있다. null이 될 수 있는 객체를 스트림으로 만들어야 할 때도 있다. 예를 들면 System.getProperty
는 제공된 키에 대응하는 속성이 없으면 null을 반환한다. 그런 메소드를 스트림에 활용하려면 다음처럼 null을 명시적으로 확인했어야 했다.
Stream.ofNullable
을 활용해보자.
<java />
Stream<String> homeValueStream = Stream.ofNullable(System.getProperty("home"));
3.3. 배열로 스트림 만들기
배열을 인수로 받는 정적 메서드 Arrays.stream을 이용하여 스트림을 만들 수 있다.
<code />
int [] numbers = {2,3,4,5,6,7};
int sum = Arrays.stream(numbers).sum();
3.4. 파일로 스트림 만들기
자바의 NIO API(비블록 I/O)도 스트림 API를 활용할 수 있도록 업데이트되었다. java.nio.file.Files의 많은 정적 메서드가 스트림을 반환한다.
3.5. 함수로 무한 스트림 만들기
iterate와 generate에서 만든 스트림은 요청할 때마다 주어진 함수를 이용해서 값을 만든다. 따라서 무제한으로 값을 계산할 수 있지만, 보통 무한한 값을 출력하지 않도록 limit(n) 함수를 함께 연결해서 사용한다.
3.5.1. tream.iterate
<code />
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
3.5.2. Stream.generate
<code />
public static Stream generate(Supplier s)