List<String> names = new ArrayList<>();
names.add("hyunsik");
names.add("aaa");
names.add("bbb");
names.add("ccc");
Stream<String> stringStream = names.stream().map(String::toUpperCase);
// stringStream은 그저 List에 있는 name들을 대문자한 스트림일 뿐이다.
// stringStream이 생성되었다고 해서 List안에 있는 names들이 대문자로 바뀌는 것이 아니다.
스트림으로 처리하는 데이터는 오직 한번만 처리한다.
무제한일 수도 있다. (Short Circuit 메소드를 사용해서 제한할 수 있다.) ex) 처음 10개 데이터만 받을래!!
스트림 오퍼레이션은 크게 중개 오퍼레이션과 종료 오퍼레이션으로 나눌 수 있다.
Stream을 리턴한다.
Stateless / Stateful 오퍼레이션으로 더 상세하게 구분할 수도 있다.
filter, map, limit, skip, sorted ...
중개 오퍼레이션 | 종료 오퍼레이션 | |
---|---|---|
리턴 타입 | Stream | Stream이 아닌 다른 타입 Ex) List, Collection... |
Stream<String> mapStream = names.stream()
.map(s -> {
System.out.println(s);
return s.toUpperCase();
});
결과 :
(System.out.println이 출력되지 않음)
System.out.println("=====================");
List<String> toUpperNameList = names.stream()
.map(s -> {
System.out.println("중개 오퍼레이션 실행!!");
return s.toUpperCase();
})
.collect(Collectors.toList());
toUpperNameList.forEach(System.out::println);
System.out.println("=====================");
System.out.println("names List는 그대로 입니다!!");
names.forEach(System.out::println);
System.out.println("=====================");
결과 :
(종료 오퍼레이션이 있어야 중개 오퍼레이션이 실행된다.)
for (String name : names) {
if (name.startsWith("h")) {
System.out.println(name.toUpperCase());
}
}
위와 같이 iterator를 사용하면 병렬적으로 처리하기 힘들다.
List<String> collect = names.parallelStream().filter(n -> n.startsWith("h")).map(s -> {
System.out.println(s + " " + Thread.currentThread().getName());
return s.toUpperCase();
}).collect(Collectors.toList());
collect.forEach(System.out::println);
parallelStream()를 사용하여 병렬적으로 처리할 수 있다.
cf) 병렬적 처리가 무조건 빠르건 아니다.
결과 :