컬렉션에 저장된 엘리먼트들을 하나씩 순회하면서 처리할 수 있는 기능.
람다식과 함께 사용할 수 있으며 컬렉션에 들어있는 데이터에 대한 처리를 간결하게 표현 가능.
내부 반복자를 사용하기 때문에 병렬처리가 쉬움.
1. 스트림은 원본을 변경하지 않는 읽기 전용.
2. 스트림은 iterator 처럼 한번만 사용되고 사라짐. 필요하면 다시 스트림을 생성해야함.
3. 최종 연산 전까지 중간 연산이 처리되지 않음.
4. 병렬 처리가 용이.
배열, 컬렉션 -> 스트림 생성 -> 매핑 -> 필터링 -> 결과
스트림은 1회용으로만 사용할 수 있다.
최종연산(ex.forEach)등이 수행된 스트림은 재사용할 수 없다. 재사용하면 java.lang.IllegalStateException이 발생한다.
자바 스트림의 연산은 크게 중간 연산과 최종 연산으로 나눌 수 있습니다. 각각의 기능을 하나씩 쉽게 설명합니다.[1][2][5][8]
1. map()
Stream<String> stream = Stream.of("a", "b");
Stream<String> mapped = stream.map(str -> str.toUpperCase()); // A, B2. filter()
Stream<String> stream = Stream.of("Apple", "Banana");
Stream<String> filtered = stream.filter(str -> str.startsWith("A")); // Apple3. flatMap()
List<List<String>> lists = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d")
);
Stream<String> flatMapped = lists.stream().flatMap(List::stream); // a, b, c, d1. collect()
List<String> result = stream.collect(Collectors.toList());2. forEach()
stream.forEach(System.out::println);3. reduce()
int sum = Stream.of(1, 2, 3).reduce(0, Integer::sum); // 6각 연산이 어떤 역할을 하는지 감이 올 거예요. 중간 연산(map, filter, flatMap)은 새로운 스트림을 만들어 이어 붙이고, 최종 연산(collect, forEach, reduce)은 실제 값을 만들거나 스트림을 끝냅니다.
age -> System.out.println(age) 이거의 축소판 = System.out::println