스트림
1. 데이터 소스를 추상화한다.
2. 데이터를 다루는데 자주 사용되는 메서드들을 정리해놓았다.
-
스트림을 사용하면 배열, 컬렉션 뿐만 아니라 파일에 저장된 데이터도 모두 같은 방식으로 다룰 수 있다는 큰 장점을 갖는다.
※ 데이터 소스를 추상화한다는 의미는 다음과 같다.
1. 데이터 소스가 무엇이든 간에 같은 방식으로 다룰 수 있게 되었다.
2. 코드의 재사용성이 높아졌다
스트림의 특징
- 스트림은 데이터 소스를 변경하지 않는다.
-> 스트림은 데이터 소스로부터 데이터를 읽기만 할 뿐 데이터 소스를 변경하지 않는다는 차이가 있다.
필요하다면 정렬된 결과를 컬렉션이나 배열에 담아서 반환할 수도 있다.
- 스트림은 일회용이다.
-> 스트림은 Iterator처럼 일회용이다. Iterator로 컬렉션의 요소를 모두 읽고 나면 다시 사용할 수 없는 것처럼
스트림도 한 번 사용하면 닫혀서 다시 사용할 수 없다. 필요하다면 스트림을 다시 생성해야만 한다.
- 스트림은 작업을 내부 반복으로 처리한다.
-> 스트림 작업이 간결한 이유 중 하나는 스트림이 '내부 반복'이기 때문이다.
'내부 반복'이라는 것은 반복문을 메서드의 내부에 숨길 수 있다는 것을 의미한다.
for(String str : strList){
System.out.println(str);
}
==================>
stream.forEach(System.out::println);
- 스트림의 연산
-> 스트림이 제공하는 다양한 연산을 활용하여 복잡한 작업들을 간단히 처리할 수 있다.
스트림이 제공하는 연산은 "중간 연산"과 "최종 연산"으로 분류할 수 있는데,
중간 연산은 연산 결과를 스트림으로 반환하기 때문에 중간 연산을 연속해서 연결할 수 있다.
반면에 최종 연산은 스트림의 요소를 소모하면서 연산을 수행하므로 단 한번만 연산이 가능하다.
중간 연산 : 연산 결과가 스트림인 연산, 스트림에 연속해서 중간 연산이 가능하다.
최종 연산 : 연산 결과가 스트림이 아닌 연산, 스트림의 요소를 소모하므로 단 한번만 가능하다.
- 지연된 연산
-> 스트림 연산에서 최종 연산이 수행되기 전까지는 중간 연산이 수행되지 않는다.
스트림 연산에 있어서 중간 연산을 호출하는 것은 단지 어떤 작업이 수행되어야 하는지를 지정해줄 뿐으로,
최종 연산이 수행되어야 비로소 스트림 요소들이 중간 연산을 거쳐 최종 연산에서 소모된다.
- 병렬 스트림
-> 스트림으로 데이터를 다룰 때의 장점 중 하나가 바로 병렬 처리가 쉽다는 것이다.
- parallel() : 병렬로 연산을 수행
- sequential() : 병렬로 처리되지 않게 하는 메서드로 parallel()을 호출한 것을 취소할 때만 사용한다.
List 형태의 데이터
Stream으로 변환