빅데이터의 등장으로 함수형 프로그래밍이 각광을 받고 있다.
함수형 프로그래밍은 멀티쓰레드가 가능하여 병렬처리가 가능하기 때문이다.
이러한 병렬처리를 해주는 자바의 기능 스트림을 소개한다.
다양한 데이터 소스 (컬랙션, 배열)를 표준화된 방법으로 다루기 위한것
기존에 List, Set, Map으로 표준화 하려 했으나 실패하고 나온 본격적인 것이다.
표준화를 하려는 이유는 뭘까?
기존에는 데이터 소스마다 중간연산의 방법 최종 결과를 내는 방법이 다 달랐다. 하지만 스트림이 등장하여 모든걸 통일할 수 있게 되었다.
List<Integer> list = Arrays.asList(1,2,3,4,5);
Stream<Integer> intStream = list.stream; // 컬렉션
Stream<String> strStream = Stream.of(new String[] { "a", "b", "c"}); // 배열
Stream<Integer> evenStream = Stream.iterate(0, n->n+2); // 0,2,4,6...
Stream<Double> randomStream = Stream.generate(Math::random); // 람다식
IntStream intStream = new Random().ints(5); // 난수 스트림(크기가 5)
다음 예시를 보자.
stream.distinct().limit(5).sorted().forEach(System.out::printn)
String[] strArr = { "dd", "aaa", "CC", "cc", "b" };
Stream<String> stream = Stream.of(strArr); // 문자열 배열이 소스인 스트림
Stream<String> filteredStream = stream.filter(); // 걸러내기 (중간 연산)
Stream<String> distinctedStream = stream.distinct(); // 중복제거(중간 연산)
Stream<String> sortedStream = stream.sort(); // 정렬 (중간 연산)
Stream<String> limitedStream = stream.limit(5); // 스트림 자르기(중간연산)
int total = stream.count(); // 요소 개수 세기 (최종 연산)
List<Integer> list = Arrays.asList(3,1,5,4,2);
List<Integer> sortedList = list.stream().sorted() // list를 정렬해서
.collect(Collectors.toList()); // 새로운 list에 저장
System.out.println(list); // [3,1,5,4,2]
System.out.println(sortedList); // [1,2,3,4,5]
Iterator 처럼 일회용이다. (필요하면 다시 스트림을 생성해야한다.)strStream.forEach(System.out::println); // 모든 요소를 화면에 출력(최종연산)
int numOfStr = strStream.count(); // 에러, 스트림이 이미 닫혔음.
IntStream intStream = new Random().ints(1,46); // 1~45 범위의 무한 스트림
intStream.distinct().limit(6).sorted() // 중간 연산
.forEach(i -> System.out.println(i + ",")); // 최종 연산
무한 스트림이라고 생각하면 어떻게 중복을 제거하고 6개를 자르나 라는 생각이 들수도 있으나 스트림은 지연된 연산을 진행하기 때문에 일단 중간 연산에 필요한 모든걸 고려해두고 필요할때 불러서 처리한다.
for(String str : strList)
System.out.println(str);
위의 반복문을 다음과 같이 편리하게 처리가능하다.
stream.forEach(System.out::println);
이게 가능한 이유는 메서드안에 기능이 포함되어 있기 때문이다.
void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action); // 매개변수의 널 체크
for(T t : src) // 내부 반복
action.accept(T);
}
Stream<String> strStream = Stream.of("dd","aaa", "CC", "cc", "b");
int sum = strStream.parallel() // 병렬 스트림으로 전환 (속성만 변경)
.mapToInt(s -> s.length()).sum(); // 모든 문자열의 길이의 합
sequential() 이용Stream<Integer> 대신 IntStream 사용)오토박싱 : 기본형을 참조형으로 바꾸는 과정
(예시)1 (기본형) -> new Integer(1) (참조형)
Stream<T> 의 경우, T에는 기본형이 들어갈수 없고 참조형만 가능하다. 그래서 오토박싱 언박싱 과정이 불가피한데 이는 시간을 많이 잡아먹는 작업이다. 이러한 비효율을 제공하기 위해 기본형 스트림을 제공하고 있다.
Stream<T> 보다 더 많이 제공영어단어 스트림을 번역하면 어떤 흐름을 의미한다. 스트림은 데이터 모음을 변환하며 생성되고 데이터들에 한해 어떤 중간 연산과정을 거치게하고 최종 단한번의 연산으로 결과를 만들어내고 소멸된다.
스트림의 등장으로 빅데이터의 빠른 병렬처리가 가능해졌다는 것에 의의를 두고자 한다.