자바의 Stream() API
다양한 데이터(컬렉션 - List,Set,Map 등, 배열 등) 소스를 표준화된 방법으로 다루기 위해서 사용합니다.
Stream<T> Collection.stream();
stream() 메소드로 간단하게 컬렉션을 stream으로 만들 수가 있다.
기본적인 형식이 있는데 스트림 파이프라인이라고 한다.
1. 스트림을 생성한다.
2. 중간 연산을 한다.
3. 최종 연산을 한다.
여기서 중간연산은 제한이 없습니다.
최종 연산은 1번만 가능합니다.
최종 연산 후에는 스트림 파이프라인이 닫힌다.
stream.limit(5).sorted.forEach(System.out::println);
스트림을 활용하여 간단하게 5개로 자르고 정렬한 뒤 출력한 것이다.
스트림의 특징으로는
1. 데이터 소스로부터 데이터를 읽기만 할 뿐 변경 되지 않습니다.
List<Integer> list = Arrays.asList(5,4,3,2,1);
List<Integer> sortedList = list.stream().sorted() //리스트 정렬
.collect(Collectors.toList()); //새로운 List에 저장
System.out.println(list); //[5,4,3,2,1] 기존 list 변경 x
System.out.println(sortedList); //[1,2,3,4,5]
2. 최종 연산 후에 재사용시 다시 생성해야 한다.
stream.limit(5).sorted.forEach(System.out::println);
이처럼 최종 연산을 한 후에는 재사용을 하기 위해서는 다시 stream을 생성해 주어야한다.
3. 최종 연산 전까지 중간연산이 수행되지 않습니다. 이것을 지연된 연산이라고 합니다.
IntStream intStream = new Random().ints(1,100) //1~99
IntStream.distinct().sorted() //중간연산
.forEach(System.out::println); //최종연산
이 코드를 보게되면 1~99의 랜덤수를 무한하게 발생시킨다.
이 때 distinct()로 중복을 제거하고 sorted()로 정렬을 하게된다.
무한한데 중복을 제거가 가능한가 싶은 생각이 드는 것이 정상이다.
그렇지만 스트림은 가능하다. 중간연산을 수행하지 않고, 필요할 경우에 수행하게 된다.
stream().map((s) -> {
System.out.println(s);
return s.toUpperCase();
};
// 실행되지 않는다.
여기 소스로 보면 System.out.println(s)가 실행되어야 한다. 하지만
실행되지 않는다. 중간연산자만 있을 뿐 최종연산이 없기 때문이다.
4. 내부적으로 처리한다.
//기존 향상된 for
for(String str : strList)
System.out.println(str);
//stream.forEach
stream.forEach(System.out::println); //최종연산
//코드가 간결해진다.
void forEach(Consumer<? super T> action){
Objects.requireNonNull(action); //매개변수의 널 체크
for(T t : src) //내부 반복(for문을 함수로 만들었다.)
action.accept(T);
}
// 이러첨 for문을 함수로 만들어서 내부적으로 처리.
for를 함수로 만들어서 내부적으로 처리한다.
5. 병렬스트림을 통해 병렬 처리가 가능하다.
parelleStream()
datasource.parellelStream().map(String::toUpperCase)
.collect(Collectors.toList());
collect.forEach(System.out::println);
//parellelSteram()은 Stream을 멀티쓰레드로 처리한다.
Stream<String> strStream = Stream.of("kim","lee","pack");
int sum = strStream.parallel() //병렬 스트림으로 전환
.mapToInt(s -> s.length()).sum);
일반 Stream()으로 처리하게 되면 같은 쓰레드에서 처리를 하게 된다.
하지만 parellsStream()을 사용하면 서로 다른 쓰레드에서 처리되는 것을 확인 할 수 있다.
스트림은
Stream<T> 로서 참조형만 가능하다.
그래서 기본형인 int나 double, long 등 기본형이 들어가면 참조형으로 변환되는 오토박싱이 된다.
(int형 배열{1,2,3} -> Stream 변환시 new Integer(1) new Integer(2) new Integer(3))
그것을 계산하기 위해서 다시 참조형 -> 기본형 으로 변환되는 언박싱이 된다.
이렇게 기본적으로 변환을 해주지만 데이터가 많을 경우 변환되는 시간마저 비효율적이기 때문에,
기본형 스트림이 존재한다.
IntSteam, LongStream, DoubleStream (Stream<Integer> -> IntStream)
숫자형인지 알기 때문에 메서드를 Stream<T>보다 더 많이 제공한다.
'Back-End > JAVA' 카테고리의 다른 글
aws s3 오브젝트 스토리지 http 오류 (0) | 2024.11.13 |
---|---|
Predicate<T> interface (0) | 2021.04.29 |
자바8 Function<T,R> interface (0) | 2021.04.26 |
자바8 - 인터페이스의 기본 메소드와 스태틱 메소드 (0) | 2021.04.08 |
자바 indexOf() - 문자열 중 해당문자 위치 찾기 (0) | 2021.04.07 |