그림에서 이해하는 목록 처리 - java8 stream/javaslang -
형마저 파악하면 8할방 알 수 있었던 것 같은 것이므로, 그것을 그림으로 해 볼게.
덧붙여서, 기사는 길지만 최초의
[本編 -
라고 표제의 개소까지 읽으면 충분하다!역시 냉정하게 생각하면 너무 길기 때문에 분할했다.
[본편 - java8 stream]: filter, map, reduce
기본의 3손을 누르자.
reduce
에는 친숙하지 않을지도 모르지만, Google 가 제창했다 MapReduce
모델이므로 map
와는 함께 말할 수 있어. -> 위키아래의 예제를 사용해 봐 갈게.
/*
* 以下の様なログがある
* ラベル もしくは ラベル:millisec の形式で1行ずつ出力される
*
* millisec の総和を求めよ
*/
List<String> lines = Arrays.asList(
"application-boot", "access-dispatch:10", "dispatched", "authentication:30", "database-access:45", "response-creation:15", "access-logging"
);
중요한 것은 어쨌든 형이므로, Generics 에 비비지 않고 거기만은 확실히 확인해 갈거야.
그리고 이런 그림이 대량으로 나올거야.
A -> B f
라고 써 있는 것은 java 의 코드로 하면 B f(a);
라고 하는 것으로, A
이나 B
에는 String
이나 Optional<Integer>
등의 구체형이 들어갑니다. 즉 Generics 입니다.filter
filter
의 정의는 다음과 같다.Stream<T> filter(Predicate<? super T> predicate);
Predicate<T>
는 「인수가 T
로 반환값이 bool
? super T
의 형표기를 Predicate<T>
라고 잡고, T を bool にする
라고 써 보자.그런 다음 Generics도 단순화됩니다.
Stream<T> filter((T -> bool) f);
(T -> bool)
를 사용하여 filter
를 lines
의 한 행에만 만드는 것은 이렇게 쓸 수 있다.lines.stream()
.filter(line -> line.contains(":")) // ["access-dispatch:10", "authentication:30", "database-access:45", "response-creation:15"]
정의를
:
라고 써 보면, 구현의 T -> bool
가 같게 보인다.(이 주제에서는
line -> line.contains(":")
는 구체적으로는 T
라는 것)그림에 그리면 이런 느낌일까.
String
는 형은 변하지 않고, 수가 바뀌는 변환이라는 것이다.맵
filter
의 정의는 다음과 같다.<R> Stream<R> map(Function<? super T, ? extends R> mapper);
이쪽도 똑같이 간략화하면 이렇다.
Stream<R> map((T -> R) f);
map
를 사용하여 map
의 행을 ラベル:millisec
로 하는 것은, Integer
의 계속에 이렇게 쓸 수 있다.lines.stream()
.filter(line -> line.contains(":")) // ["access-dispatch:10", "authentication:30", "database-access:45", "response-creation:15"]
.map(line -> Integer.valueOf(line.split(":")[1])) // [10, 30, 45, 15]
여기도 정의의
filter
와 구현이 같은 형태를 하고 있다.(이 주제에서는,
T -> R
는 구체적으로는 R
라는 것이니까, Integer
가 T -> R
로 보이고 있으면 좋은 느낌)그림에 그리면 이런 느낌일까.
String -> Integer
는 수는 변하지 않고, 형이 바뀌는 변환이라는 것이다.reduce
map
의 정의는 java8 stream 에는 3개 있습니다만, 지금부터 사용하는 것은 이렇다.T reduce(T identity, BinaryOperator<T> accumulator);
reduce
는 조금 낯설지만, 「인수가 BinaryOperator<T>
를 2개로 반환값도 T
」라고 하는 것이다.이것도 비비하지 않고 간략화해 보자.
T reduce(T t, ((T, T) -> T) f);
T
는 일반적으로 「컨벌루션」이라고 말해져 있어 리스트의 선두로부터 순서대로 결과를 축적해 가는 처리이다.reduce
를 사용하여 reduce
의 줄을 Integer
의 합계로 만드는 것은 Integer
의 다음에 이렇게 쓸 수 있다.lines.stream()
.filter(line -> line.contains(":")) // ["access-dispatch:10", "authentication:30", "database-access:45", "response-creation:15"]
.map(line -> Integer.valueOf(line.split(":")[1])) // [10, 30, 45, 15]
.reduce(0, (acc, n) -> acc + n) // 100
정의에 조금 괄호가 많지만,
map
와 T, (T, T) -> T
가 같은 형태를 하고 있기 때문에 조금은 알기 쉬워야 한다.그림에 그리면 이런 느낌일까.
0, (acc, n) -> ...
는 리스트의 요소가 단일의 결과가 되는 처리이다.요약
이것으로 클리어!
* millisec の総和を求めよ
는
// ( 再掲 )
lines.stream()
.filter(line -> line.contains(":")) // ["access-dispatch:10", "authentication:30", "database-access:45", "response-creation:15"]
.map(line -> Integer.valueOf(line.split(":")[1])) // [10, 30, 45, 15]
.reduce(0, (acc, n) -> acc + n) // 100
에서 풀었다.
일단 전체 그림을 올려 놓는다.
끝
여기에서 앞의 모든 덤은 아래의 기사로 분리했다.
그림에서 이해하는 목록 처리 - java8 stream / javaslang - 덤
깨끗이.
Reference
이 문제에 관하여(그림에서 이해하는 목록 처리 - java8 stream/javaslang -), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/suzuki-hoge/items/16ab07c65f5f906cf600텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)