java8

이전에 FunctionalInterface와 람다표현식을 배웠다. 아직 못봤거나 까먹었다면 여기에가서 다시 보자!

Stream

Stream 에는 많은 기능이 있다. 다 설명할 수는 없지만 중요한 몇가지를 공부해보겠다.
자바의 컬렉션들은 Stream을 사용 할 수 있다. 혹은 스트림을 만들 수 있다.
흔히 쓰는 List<T>를 예로 들어 공부해보겠다.
그전에 알아두어야 할 용어가 있다.
Intermediate Operation MethodTerminal Operation Method이다.
Intermediate Operation Method는 중간단계로써 스트림을 리턴하기 때문에 계속 Method Chaining 통해 지시 할 수 있다.
그리고 Terminal Operation Method는 스트림을 끝내는 메소드다. Stream은 Lazy 하기 때문에 이 메소드가 호출되면 그때서야 Intermediate Method를 실행한다.

Optional<T> reduce(BinaryOperator<T> accumulator)
void forEach(Consumer<? super T> action)
Optional<T> max(Comparator<? super T> comparator)
long count()
Optional<T> findFirst()

등이 Terminal Operation Method에 속한다.
한번 코드를 보자!

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
System.out.println(numbers.stream().reduce((i, j) -> i + j).get());
numbers.stream().forEach(x -> System.out.print(x + " "));
System.out.println();
System.out.println(numbers.stream().max((i, j) -> i.compareTo(j)).get());
System.out.println(numbers.stream().min((i, j) -> i.compareTo(j)).get());
System.out.println(numbers.stream().count());
System.out.println(numbers.stream().findFirst().get());

두 번째의 reduce는 합치는 작업을 한다. i + j의 합이 다시 i 가 되고 j 는 다음번숫자로 넘어가는걸 반복한다.
forEach는 우리가 흔히 썼던 for each 문과 같다.
max는 말그대로 최대값을 찾는다. min도 마찬가지다.
count는 스트림안에 개수를 리턴한다.
findFirst는 첫 번째 있는 값을 가져온다.

Stream<T> filter(Predicate<? super T> predicate)
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
Stream<T> sorted()
Stream<T> limit(long maxSize)

등이 Intermediate Operation Method에 속한다. 이 외에도 많이 있다.
마찬가지로 코드로 보자!

numbers.stream().filter(i -> i > 5).forEach(x -> System.out.print(x + " "));
System.out.println();
numbers.stream().map(i -> i * 2).forEach(x-> System.out.print(x + " "));
System.out.println();
numbers.stream().sorted((i, j) -> j.compareTo(i)).forEach(x -> System.out.println(x));
numbers.stream().limit(4).forEach(x -> System.out.println(x));

filter는 말그대로 걸러주는 역할을 한다. 파라미터가 Predicate이다 Predicate은 boolean 값을 리턴한다.
map은 어떤타입을 다른타입 혹은 같은타입으로 변환해준다. 위 코드는 2배를 해주는 코드다.
flatMap은 map이랑 같지만 Stream타입을 리턴한다.
sorted는 정렬을 해주는 함수다. 위의 코드는 내림차순으로 정렬한 코드다.
limit는 개수는 제한하는 코드다 mysql의 limit와 같다.
그럼 한번 응용을 해보자.
1~9까지중 3보다 큰값을 골라 2배를 해주고 내림차순으로 정렬뒤 3개만출력하는 코드를 구현해보자. 간단하게 구현 할 수 있다.

numbers.stream()
        .filter(i -> i > 3)
        .map(i -> i * 2)
        .sorted((i,j) -> j.compareTo(i))
        .limit(3)
        .forEach(x -> System.out.println(x));

간단하게 Stream에 대해서 알아봤다.
어느정도 감만 잡았다면 성공한거다.
다음 시간엔 method reference 대해서도 알아보겠다.