Stream
- 데이터 소스를 추상화하고, 데이터를 다루는데 자주 사용되는 메서드들을 정의해 놓은 것.
- 데이터 소스를 추상화하면 데이터 소스가 무엇이던 간에 같은 방식으로 다룰 수 있게 되었다는 것과 코드의 재사용성이 높아진다는 것을 의미한다.
- 배열이나 컬렉션뿐만 아니라 파일에 저장된 데이터도 모두 같은 방식으로 다룰 수 있다.
- stream은 데이터 소스를 변경하지 않는다.
- 데이터를 읽기만할 뿐, 변경하지 않는다. 필요시 컬렉션이나 배열에 담아서 반환할 수도 있다.
- stream은 일회용이다.
- Iterator처럼 일회용이다. 스트림도 한 번 사용하고 닫히면 다시 사용할 수 없다. 필요하다면 다시 stream을 생성해야한다.
- stream은 작업을 내부 반복으로 처리한다.
- 내부 반복이라는 것은 반복문을 메서드의 내부에 숨길 수 있다는 것을 의미한다.
- forEach()는 스트림에 정의된 메서드 중 하나로 매개변수에 대입된 람다식을 데이터 소스의 모든 요소에 적용한다.
Stream의 연산
중간 연산과 최종 연산으로 분류할 수 있다.
- 중간 연산은
- 연산 결과를 스트림으로 반환하기 때문에 연속해서 연결할 수 있다.
- 중간 연산은 map(), flatMap()
- 최종 연산은
- 스트림의 요소를 소모하면서 연산을 수행하기 때문에 단 한번만 연산이 가능하다.
- 최종 연산은 reduce(), collect()
stream.distinct(0).limit(5).sorted().forEach(System.out::println)
// distinct() : 중간연산
// limit() : 중간연산
// sorted() : 중간연산
// forEach() : 최종연산
지연된 연산
- 스트림 연산은 최종 연산이 수행되기 전까지 중간 연산이 수행되지 않는다.
- 스트림의 distinct()나 sort() 같은 중간 연산을 호출해도 연산이 수행되지 않는다.
- 최종 연산이 수행되어야 중간 연산을 거쳐 최종 연산에서 소모된다.
병렬 스트림
- 병렬 스트림은 내부적으로 프레임워크를 이용해서 자동적으로 연산을 병렬로 수행한다.