스트림이란?
java 8부터 사용 가능한 컬랙션 및 배열의 요소를 반복처리 하기 위한 기능이다.
스트림은 요소들이 하나씩 흘러가면서 처리된다는 의미를 가지고 있다.
list 컬렉션에서 요소를 반복처리하기 위해 스트림을 사용하면 다음과 같다.
Stream<String> stream = list.stream();
stream.forEach(item -> /*item 처리*/);stream은 Iterator와 비슷한 반복자이지만, 다음과 같은 차이점이 있다.
1. 내부 반복자이므로 처리 속도가 빠르고 병렬 처리에 효율적이다.
2. 람다식으로 다양한 요소 처리를 정의할 수 있다.
3. 중간 처리와 최종 처리를 수행하도록 파이프라인을 형성할 수 있다.
내부 반복자
우리는 for문과 while문을 등을 이용할때, 요소를 컬렉션 밖으로 반복해서 가져와 처리하게 되는데,
이것을 외부 반복자라고 한다.
반면 스트림은 요소 처리 방법을 컬렉션 내부로 주입시켜서 요소를 반복처리하는 데,
이것을 외부 반복자라고 한다.

중간처리와 최종처리
스트림 파이프라인
스트림은 하나 이상 연결될 수 있다.
다음과 같이 여러 스트림이 연결되어 있는것을 스트림 파이프라인이라고 한다.

중간 스트림들은 최종 처리를 외해 요소를 걸러내거나 (필터링), 요소를 변환시키거나 (매핑), 정렬하는 작업을 수행한다.
최종 처리는 중간 처리에서 정제된 요소들을 반복하거나, 집계 작업을 수행한다.
리소스로부터 스트림 얻기
| 리턴 타입 | 메소드 | 리소스 |
|---|---|---|
| Stream | java.util.Collection.stream() | List 컬렉션 |
| java.util.Collection.parallelStream() | Set 컬렉션 | |
| Stream | Arrays.stream(T[ ]) | 배열 |
| Stream.of(T[ ]) | 배열 | |
| IntStream | Arrays.stream(int[ ]) | |
| IntStream.of(int[ ]) | ||
| LongStream | Arrays.stream(long[ ]) | |
| LongStream.of(long[ ]) | ||
| DoubleStream | Arrays.stream(double[ ]) | |
| DoubleStream.of(double[ ]) | ||
| IntStream | IntStream.range(int, int) | int 범위 |
| IntStream.rangeClosed(int, int) | int 범위 | |
| LongStream | LongStream.range(long, long) | long 범위 |
| LongStream.rangeClosed(long, long) | long 범위 | |
| Stream | Files.list(Path) | 디렉토리 |
| Stream | Files.lines(Path, Charset) | 텍스트 파일 |
| DoubleStream | Random.doubles(…) | 랜덤 수 |
| IntStream | Random.ints() | |
| LongStream | Random.longs() |
각 메서드를 사용해서 원하는 타입의 스트림을 받아올 수 있다.
필터링
필터링은 요소를 걸러내는 중간 처리 기능이다.
필터링 메소드에는 다음과 같이 distinct() 와 filter()가 있다.
distinct() 메소드는 요소의 중복을 제거한다.
객체 스트림일 경우엔 equals() 메소드를 기준으로 판단한다.
filter() 메소드드는 인자값으로 람다식을 받고 그 람다식이 리턴하는 boolean 타입의 값을 기준으로 판단한다.
아래 코드는 성이 남씨인 사람만 출력하는 예제 코드이다.
import java.io.*;
import java.math.*;
import java.util.*;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) throws Exception {
ArrayList<String> al = new ArrayList<String>();
al.add("남병철");
al.add("강철근");
al.add("남수근");
al.stream().filter(str->{
if(str.charAt(0)=='남') {
return true;
}
return false;
}).forEach(str->{
System.out.println(str);
});
bw.flush();
bw.close();
br.close();
}
}//출력:
//남병철
//남수근