자바 8 스트림 API 특징
- 선언형 : 더 간결하고 가독성이 좋아진다.
- 조립할 수 있음 : 유연성이 좋아진다.
- 병렬화 : 성능이 좋아진다.
학습에 사용할 클래스
package com.company;
public class Dish {
private final String name;
private final boolean vegetarian;
private final int calories;
private final Type type;
public Dish(String name, boolean vegetarian, int calories, Type type) {
this.name = name;
this.vegetarian = vegetarian;
this.calories = calories;
this.type = type;
}
public String getName() {
return name;
}
public boolean isVegetarian() {
return vegetarian;
}
public int getCalories() {
return calories;
}
public Type getType() {
return type;
}
@Override
public String toString() {
return name;
}
public enum Type {MEAT, FISH, OTHER}
}
스트림이란?
데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소
- 연속된 요소 : 컬렌션과 마찬가지로 연속된 값 집합의 인터페이스 제공, 컬렉션의 주제는 데이터고 스트림의 주제는 계산!!!
- 소스 : 정렬된 컬렉션으로 스트림을 생성하면 정렬이 그대로 유지, 리스트로 스트림을 만들면 같은 순서!!
- 데이터 처리 연산 : 함수형 프로그래밍 언어에서 일반적으로 지원하는 연산과 데이터베이스와 비슷한 연산을 지원
특징
- 파이프 라이닝 : 대부분의 스트림 연산은 연산끼리 연결해서 커다란 파이프 라인을 구성할 수 있도록 스트림 자신을 반환한다.
- 내부 반복 : 내부 반복자 지원
List<Dish> menu = Arrays.asList(
new Dish("pork", false, 800, Dish.Type.MEAT),
new Dish("beef", false, 700, Dish.Type.MEAT),
new Dish("chicken", false, 400, Dish.Type.MEAT),
new Dish("french", true, 530, Dish.Type.OTHER),
new Dish("rice", true, 350, Dish.Type.OTHER),
new Dish("season fruit", false, 120, Dish.Type.OTHER),
new Dish("pizza", true, 550, Dish.Type.OTHER),
new Dish("prawns", false, 300, Dish.Type.FISH),
new Dish("salmon", false, 450, Dish.Type.FISH)
);
List<String> threeHighCaloricDishNames =
menu.stream() // 스트림 얻음
.filter(dish -> dish.getCalories() > 300) // 고칼로리 요리를 필터링
.map(Dish::getName) // 요리명 추출
.limit(3) // 선착순 세 개만 선택
.collect(Collectors.toList()); // 결과를 리스트로 저장
System.out.println(threeHighCaloricDishNames);
- filter : 람다를 인수로 받아 스트림에서 특정 요소를 제외시킨다.
- map : 람다를 이용해서 한 요소를 다른 요소로 변환하거나 정보를 추출한다. ( 요리명 추출 Dish::getName, d -> d.getName())
- limit : 정해진 개수 이상의 요소가 스트림에 저장되지 못하게 스트림 크기 축소
- collect : 스트림을 다른 형식으로 변환
스트림과 컬렉션
- 컬렉션은 현재 자료구조가 포함하는 모든 값을 메모리에 저장하는 자료구조
- 스트림은 이론적으로 요청할 때만 요소를 계산하는 고정된 자료구조
- - 컬렉션이 DVD라면 스트림은 비디오 스트리밍
딱 한번만 탐색 할 수 있다.
List<String> title = Arrays.asList("Java8", "In","Action");
Stream<String> s = title.stream();
s.forEach(System.out::println); // title 각 단어를 출력
s.forEach(System.out::println); // 스트림이 이미 소비되었거나 닫힘
- 외부 반복 : 컬렉션 인터페이스를 사용해서 사용자가 직접 요소를 반복 (for-each, for ...)
- 내부 반복 : 반복을 알아서 처리하고 결과 스트림값을 어딘가에 저장해주는 스트림 라이브러리가 사용
// for-each 를 사용하는 외부 반복
List<String> names = new ArrayList<>();
for(Dish dish: menu){
names.add(dish.getName());
}
// 스트림 : 내부 반복
List<String> names = menu.stream()
.map(Dish::getName)
.collect(Collectors.toList());
외부 반복은 병렬성을 스스로 관리해야 하지만 스트림 라이브러리의 내부 반복은 병렬성 구현을 자동으로 선택한다.
스트림 연산
중간 연산
- 다른 스트림을 반환하는 연산
- 여러 중간 연산을 연결해서 질의를 만들 수 있다.
- filter, map, limit, sorted, distinct
최종 연산
- 스트림 파이프라인에서 결과를 도출한다.
- forEach, count, collect
스트림 이용과정
- 질의를 수행할 데이터 소스 (컬렉션 같은)
- 스트림 파이프라인을 구성할 중간 연산 연결
- 스트림 파이프라인을 실행하고 결과를 만들 최종 연산
'Java > [Java8] 모던인자바액션' 카테고리의 다른 글
스트림 활용 (0) | 2022.02.15 |
---|---|
람다 표현식 (0) | 2022.02.11 |
동작 파라미터화 코드 전달 (0) | 2022.02.09 |