1. 스트림이란 ( Stream ) ?
- JDK 8 버전에 추가됨.
- 트림은 배열, 리스트 등 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 해주는 기능
- Collection 내부의 데이터 정렬, 필터링, 중복제거등을 구현 시 필요
2. 특징
- 스트림은 원본 데이터를 변경하지 않는다.
- 스트림은 일회용이다. Iterator로 컬렉션의 요소를 모두 읽고 나면 다시 사용할 수 없는 것처럼, 스트림도 한번 사용하면 닫혀서 다시 사용할 수 없다. 필요하다면 스트림을 다시 생성해야한다.
- 람다식으로 요소 처리 코드를 제공
- 내부 반복자를 사용하므로 병렬 처리가 쉽다
- 중간 처리와 최종 처리 작업을 수행한다.
내부 반복자를 사용해서 얻는 이점은 컬렉션 내부에서 어떻게 요소를 반복시킬 것인가는 컬렉션에게 맡겨두고, 개발자는 요소 처리 코드에만 집중할 수 있다는 것입니다.
내부 반복자는 요소들의 반복 순서를 변경하거나, 멀티 코어 CPU를 최대한 활용하기 위해 요소들을 분배시켜 병렬 작업을 할 수 있게 도와주기 때문에 하나씩 처리하는 순차적 외부 반복자보다는 효율적으로 요소를 반복시킬 수 있습니다.
package stream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class ParellelExam {
public static void main(String[] args) {
List<String> list = Arrays.asList("John", "Simon", "Andy", "Andrew", "Bill");
// 순차 처리
Stream<String> stream = list.stream();
stream.forEach(ParellelExam::print);
System.out.println();
// 병렬 처리
Stream<String> parallelStream = list.parallelStream();
parallelStream.forEach(ParellelExam::print);
}
public static void print(String str) {
System.out.println(str + " : " + Thread.currentThread().getName());
}
}
출처: https://palpit.tistory.com/647 [palpit Vlog]
3. 예제
.net 개발자라면 Linq와 비슷한 용도로 사용하거나 / 이해하면 사용하기 쉬울것같다.
mybirts 나 DB를 활용해서 정렬 / 중복제거등의 연산이 수행된 결과를 반환받을 수 있으나 상황에 따라 해쉬 조인을
지원하지 않는 mysql이나 NoSQL을 사용한다거나 하는 경우 활용도가 높은것 같다.
- 객체의 값을 필터링 / 조건에 따른 연산 / 중복제거 예제
// List 형태의 객체 컬렉션에서 조건에 만족하는 값을 찾는경우
List<[객체]> 변수명 = [컬랙션].stream()
.filter([객체] -> [객체].[객체속성]equals([조건값]))
.filter([객체] -> [객체].[객체속성] != null ))
.filter([객체] -> [객체].[객체속성].equals([조건값])
// 조건이 다수인 경우 AND 조건
.filter([객체] -> [객체].[객체속성] <= [조건값] && [객체유형].[속성값] >= [조건값])
// 조건이 다수인 경우 OR 조건
.filter([객체] -> [객체].[객체속성] <= [조건값] || [객체유형].[속성값] || [조건값])
.collect(Collectors.toList());
// List 형태의 객체 컬렉션에서 조건에 만족하는 값을 찾는경우 ( 내부의 객체에 접근 )
List<[객체]> 변수명 = [컬랙션].get(0).stream()
.filter([객체] -> [객체].[객체속성]equals([조건값]))
.filter([객체] -> [객체].[객체속성] != null ))
.filter([객체] -> [객체].[객체속성].equals([조건값])
.collect(Collectors.toList());
// List 형태의 객체 컬렉션에서 조건에 만족하믄 값의 합계
String 변수명 = (int) [컬랙션].stream()
.filter(o -> o.getCount() != 0).mapToInt(o -> o.getCount())
.sum()
//중복제거 메소드
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
// 중복제거
List<객체> 변수명 = [컬랙션].stream().filter(distinctByKey(객체::[객체속성])).collect(Collectors.toList());
// 중복제거 조건이 다수인 경우
List<객체> 변수명 = [컬랙션].stream().distinct()
.filter(distinctByKey(pr -> Arrays.asList(pr.[객체속성], pr.[객체속성], pr.[객체속성])))
.collect(Collectors.toList());
- 참고사이트 주소
( 상세내용이 잘 정리되어 있습니다 )