Stream이란
(1) Stream?
Stream이란, 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소이다.
- Stream은 순차적으로 혹은 병렬적으로 실행하여 데이터를 처리할 수 있다.
- Stream은 Collection, 배열, I/O 자원 등의 데이터 제공 소스로부터 데이터를 소비한다.
- Stream은 Collection과 마찬가지로, 특정 요소 형식으로 이루어진 연속된 값 집합 인터페이스를 제공한다. Collection의 경우 요소의 저장 및 접근 연산 중심이며, Stream의 경우에는 filter, sorted, map, distinct과 같은 데이터 처리 중심이다.
(2) Stream 특징
1.Stream은 수직적으로(위에서 아래로) 동작한다.
arr.stream()
.filter(...)
.map(...)
.findFirst();
- filter -> map -> findFirst 순으로 동작한다.
2.Stream은 재사용이 불가능하다.
Stream<String> stream = Stream.of("GilSSang", "Tommo", "Dolphin").filter(name -> name.contains("o"));
Optional<String> firstTry = stream.findFirst();
Optional<String> secondTry = stream.findAny(); // IllegalStateException: stream has already been operated upon or closed
- Stream을 한 번 소비하고 난 뒤, 그 이후에 재사용할 수 없다.
3.Stream은 내부 반복을 지원한다.
- Collection은 외부 반복을 지원하기에 for 구문을 통해 사용자가 직접 처리해야한다.
- Stream은 내부 반복을 지원하기에 반복을 알아서 처리하기에 반복자를 사용할 필요가 없으며 병렬성 구현을 자동으로 선택구현할 수 있다.
4.Stream은 늦은 처리(Lazy Invocation)를 지원한다.
public class CollectionStream {
public static int length(String s) {
System.out.println(s + " length : " + s.length());
return s.length();
}
public static String substr(String s) {
System.out.println(s + " substr : " + s.substring(0, 3));
return s.substring(0, 3);
}
public static void main(String[] args) {
System.out.println("------------------");
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));
Stream<String> stream = arr.stream()
.filter(name -> length(name) > 5)
.map(name -> substr(name));
System.out.println("Stream Created");
List<String> list = stream.collect(Collectors.toList());
System.out.println("list : " + list);
System.out.println("------------------");
}
}
------------------
Stream Created
GilSSang length : 8
GilSSang substr : Gil
Tommo length : 5
Dolphin length : 7
Dolphin substr : Dol
firstLength : [Gil, Dol]
------------------
Process finished with exit code 0
Stream은 최종 연산을 진행하기 전에 중간 연산을 실행하지 않는다.
Stream은 연산을 최대한 지연(Lazy)시켜 프로그램 성능의 향상을 도모한다.
Stream 생성
(1) 배열을 통해 Stream 생성
String[] arr = new String[]{"GilSSang", "Tommo", "Dolphin"};
Stream<String> stream = Arrays.stream(arr);
- 간단하게 Arrays.stream()메소드를 통해 생성할 수 있다.
(2) 컬렉션을 통해 Stream 생성
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));
Stream<String> stream = arr.stream();
- 컬렉션 타입의 경우 인터페이스에 추가된 디포릍 메소드 stream()을 통해 생성할 수 있다.
Stream 연산
(1) 중간 연산
1.filter
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));
Stream<String> stream = arr.stream()
.filter(name -> name.length() > 5);
// ["GilSSang", "Dolphin"]
- 필터(filter)는 스트림 내 요소들을 지정한 람다식을 기반으로 하나씩 평가해서 걸러내는 작업을 진행한다.
2.map
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));
Stream<String> stream = arr.stream()
.map(name -> name.substring(0, 3));
// [Gil, Tom, Dol]
- 맵(map)은 스트림 내 요소들을 하나씩 지정한 람다식에 적용하여 값을 변환해준다.
3.sorted
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));Stream<String> stream = arr.stream() .sorted();// [Dolphin, GilSSang, Tommo]ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));Stream<String> stream = arr.stream() .sorted(Comparator.reverseOrder());// [Tommo, GilSSang, Dolphin]
- 정렬(sort)은 스트림 내 요소들을 Comparator를 이용하여 정렬을 진행한다.
4.distinct
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "GilSSang", "Tommo", "Dolphin"));Stream<String> stream = arr.stream() .distinct();
- 중복제거(distinct)은 스트림 내 요소들의 중복 요소들을 제거해준다.
(2) 최종 연산
1.forEach
스트림에서 작업한 결과를 소비하여 결과를 반환한다.
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));arr.stream() .map(name -> name.substring(0, 3)) .forEach(System.out::println);
- forEach를 사용하여 스트림에서 작업한 결과를 출력했다.
2.collect
Collector타입의 인자를 받아서 처리한다.
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));List<String> list = arr.stream() .map(name -> name.substring(0, 3)) .collect(Collectors.toList());// [Gil, Tom, Dol]
- 스트림에서 작업한 결과를 담은 리스트로 반환한다.
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));String s = arr.stream() .map(name -> name.substring(0, 3)) .collect(Collectors.joining());// GilTomDol
- 스트림에서 작업한 결과를 문자열로 이어 반환한다.
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));Integer sum = arr.stream() .map(name -> name.substring(0, 3)) .collect(Collectors.summingInt(String::length));// 9
- 스트림에서 작업한 결과 입력받은 메소드 기반으로 총합을 구한다.
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));Integer sum = arr.stream() .map(name -> name.substring(0, 3)) .collect(Collectors.averageingInt(String::length));// 3
- 스트림에서 작업한 결과를 입력받은 메소드 기반으로 평균을 구한다.
ArrayList<String> arr = new ArrayList<>(Arrays.asList("GilSSang", "Tommo", "Dolphin"));IntSummaryStatistics collect = arr.stream() .map(name -> name.substring(0, 3)) .collect(Collectors.summarizingInt(String::length));System.out.println("collect = " + collect);// IntSummaryStatistics{count=3, sum=9, min=3, average=3.000000, max=3}
- 스트림에서 작업한 결과를 입력받은 메소드 기반으로 전체적인 Summary를 구한다.
3.count
ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(1, 2, 3));long count = arr.stream() .count();
- 스트림에서 작업한 결과의 수를 반환한다.
'자바' 카테고리의 다른 글
JAVA Collection (0) | 2021.10.15 |
---|---|
JAVA Lambda, Functional Interface (0) | 2021.10.14 |
JAVA Exception (0) | 2021.10.13 |
Java Optional (1) | 2021.10.04 |
JVM, JRE, JDK (0) | 2021.09.18 |