스트림 -> 흐름
흘러가는 대상이 무엇이냐? 객체
흘러가는 객체가 하나씩 처리된다.
List는 index로 객체를 관리하고, set은 index로 관리하지 않는다.
그래서 set 객체 하나하나를 가져올 방법이 없다.
Stream<String> stream = list.stream();
stream.forEach(item -> //item처리);
다양한 데이터 소스(컬렉션, 배열)를 표준화된 방법으로 다루기 위한 것
for문은 외부 반복자이다.
stream은 내부 반복자이다.
내부 반복자는 멀티 코어 CPU를 최대한 활요하기 위해 요소들을 분배시켜 병렬 작업을 할 수 있다. 하나씩 처리하는 순차적 외부 반복자보다는 효율적으로 요소를 반복시킬 수 있는 장점이 있다.
Java 8부터는 컬렉션 및 배열의 요소를 반복 처리하기 위해 스트림을 사용할 수 있다. 스트림은 요소들이 하니씩 흘러가면서 처리된다는 의미를 가지고 있다.
Stream<String> stream = List.stream();
stream.forEach( item → //item 처리);
List 컬렉션의 stream() 메소드로 stream 객체를 얻고, forEach() 메소드로 요소를 어떻게 처리할지를 람다식을 제공한다.
stream 자체가 처리하는 방법을 갖고 있지는 않다. 외부에서 람다식으로 제공해야 한다.
1) 내부 반복자이므로 처리 속도가 빠르고 병렬 처리에 효율적
2) 람다식으로 다양한 요소 처리를 정의할 수 있다.
3) 중간 처리와 최종 처리를 수행하도록 파이프 라인을 형성할 수 있다.

출처:점프투자바
그리고 스트림은 단방향이기 때문에 입력과 출력이 동시에 발생할 수 없다. 그렇기 때문에 용도에 따라 입력스트림, 출력스트림이 나뉜다.
바이트스트림인 InputStream 을 통해 입력을 받으면 문자스트림인 InputStreamReader 을 통해 바이트 단위 데이터를 문자(character) 데이터로 처리할 수 있게 만들어준다는 것이다. 그리고 앞에서 보았듯이 Scanner 를 생성할 때 문자스트림으로 변환시켜 읽는다는 것을 알 수 있다.
즉, InputStreamReader 의 가장 큰 특징은 다음과 같다.
1. 바이트 단위 데이터를 문자(character) 단위 데이터로 처리할 수 있도록 변환해준다.
2. char 배열로 데이터를 받을 수 있다.
함수형 프로그래밍이란 함수를 정의하고 이 함수(실행블록을 가지고 있는 하나의 코드 덩어리)를 데이터 처리부로 보내 데이터를 처리하는 기법을 말한다. 데이터 처리부는 데이터만 가지고 있을 뿐, 처리 방법이 정해져 있지 않아 외부에서 제공된 함수에 의존한다.
함수 vs 메소드
함수는 객체와 상관없이 실행가능한 코드들 묶음
메소드는 객체 안에 존재, 객체 기능을 정의
자바는 함수형 프로그래밍을 지원하기 위해 Java8부터 람다식을 지원한다.
람다식: (매개변수) -> {처리 내용}
자바는 람다식을 익명 구현 객체로 변환한다. 이름이 없는 인터페이스 구현 객체를 말한다.
인터페이스의 익명 구현 객체를 람다식으로 표현하려면 인터페이스가 단 하나의 추상 메소드만 가져야 한다.