Java
[Java] Stream
삶_
2022. 6. 27. 13:46
Stream
- 다양한 데이터소스(컬렉션/배열..)를 표준화된 방법으로 다루기 위한 것
- 병렬 처리가 쉬움 (연산을 병렬로 수행)
Stream<Integer> intStream = list.stream(); //컬렉션
Stream<String> strStream = Stream.of(new String[]{"a","b","c"}) //배열
1. 스트림만들기
2. 중간연산 여러번하기
3. 최종연산
- 중간연산
- 연산결과가 스트림인 연산. 여러번 적용가능
- 걸러내기라고 보면 됨
- 최종연산
- 연산결과가 스트림이 아닌 연산. 단 한번만 적용가능
스트림의 특징
- 데이터를 읽기만 하고 변경하지 않음
- 일회용 (최종연산 후 필요하면 다시 스트림을 생성해야함)
- 최종 연산 전까지 중간연산이 수행되지 않음 (지연된 연산)
- 따라서 아래같은 코드가 가능해짐
- 작업을 내부 반복으로 처리함
스트림 생성
컬렉션
- Stream<T> Collection.stream()
- List<Integer> list = Arrays.asList(1,2,3,4,5);
Stream<Integer> intStream = list.stream();
배열
- nt[] arr = {1,2,3,4,5};
Stream<Integer> intStream = Arrays.stream(arr); 혹은
Stream<Integer> intStream = Stream.of(arr); //다양하게 됨 - IntStream intStream = IntStream.of(arr); 혹은
IntStream intStream = Arrays.stream(arr);
특정 범위의 정수
- IntStream intStream = IntStream.range(시작인덱스, 끝인덱스 포함X);
- IntStream intStream = IntStream.rangeClosed(시작인덱스, 끝인덱스도 포함);
람다식
- iterate(), generate()
- 람다식을 매개변수로 받아, 이 람다식에 의해 계산되는 값들을 요소로 하는 무한 스트림 생성
- generate() 는 iterate() 와 달리, 이전 결과를 이용해서 다음요소를 계산하지 않음
- IntStream 처럼 기본형 스트림 타입의 참조변수로 다룰 수 없음
- Stream<Double> randomStream = Stream.generate(Math::random);
그외
- 빈 스트림
- Stream emptyStream = Stream.empty(); //비어있는 스트림 생성. null 보단 이 방법 이용하기!
- 두 스트림의 연결
- concat()
- Stream<String> strs1 = Stream.of(str1);
Stream<String> strs2 = Stream.of(str2);
Stream<String> result = Stream.concat(strs1,strs2); // 두 스트림을 하나로 연결
스트림의 연산 - 중간연산
- 같은걸 중복으로 쓸수있음
skip(), limit()
forEach()
- 변수에 컬렉션 등을 넣고 나열하는것
- collection.forEach(변수 -> 반복처리(변수))
skip(n) //앞에서부터 n개 건너뛰기
limit(n) //n 이후의 요소는 잘라냄
IntStream intStream = IntStream.rangeClosed(1, 10); //12345678910 (10포함)
intStream.skip(3).limit(5).forEach(System.out::print); //45678
filter(), distinct()
filter(Predicate<? super T> n) //조건에 맞지않는 요소 제거
Stream<T> distinct() //중복 제거
IntStream intStream = IntStream.rangeClosed(1,10);
intStream.filter(i->i%2==0).forEach(System.out::print); //2의배수만 뽑기. 246810
IntStream intStream = IntStream.of(1,2,2,3,3,3,4,5,5,6);
intStream.distinct().forEach(System.out::print); //123456. 중복제거
sorted()
- sorted() //내림차순 정렬
- sorted((Comparator...)) //()에 있는 기준으로 정렬
Comparator
- Comparator의 comparing()으로 정렬기준을 제공
- sorted의 반환타입이 comparator이다
// 반별로 정렬
studentStream.sorted(Comparator.comparing(Student::getBan)).forEach(System.out::println)
- 정렬기준이 많을때는, thenComparing()을 사용
//추가 정렬 기준을 제공할 때는 thenComparing()을 사용
thenComparing(Comparator<T> other)
thenComparing(Function<T, U> keyExtractor)
thenComparing(Function<T, U> keyExtractor, Comparator<U> keyComp)
studentStream.sorted(Comparator.comparing(Student::getBan) //반별로 정렬
.thenComparing(Student::getTotalScore) //총점별로 정렬
.thenComparing(Student::getName)) //이름별로 정렬
.forEach(System.out::println);
map()
- 스트림의 요소 변환하기 (Function 을 사용)
- 원하는 필드만 뽑거나, 특정 형태로 변환해야 할 때 사용
- mapToInt(), mapToLong(), mapToDouble()
- 스트림의 값을 int형, Long형, Double형으로 변환할때
- Stream<String> -> IntStream
// file -> String 으로 변환하기 (map() 이용!)
Stream<File> fileStream = Stream.of(new File("Ex1.java"), new File("Ex1"))
new File("Ex1.bak"), new File("Ex2.java");
//map()으로, Stream<File> 을 Stream<String> 으로 변환
Stream<String> filenameStream = fileStream.map(File:getName);
filenameStream.forEach(System.out::println);
peek()
- 스트림의 요소를 소비하지 않고 조회해줌(출력해줌)
- 출력용이라고 보면 됨 (forEach()문이랑 비슷함)
flatmap()
- 스트림의 스트림을 스트림으로 변환
- 스트림의 요소가 배열일때, 예를들어 Stream<T[]> 를 Stream<T> 로 바꾸기
Stream<String[]> strArrStrm = Stream.of(new String[]{...},
new String[]{...});
// 스트림의 스트림 (map을 이용) -> 스트림을 배열로 바꿈 (스트림 해제) -> 스트림<스트림<String>>
// 이러면 결국 스트림 내에 있기 때문에 또 스트림으로 출력됨(스트림의 스트림 -> 스트림)
Stream<Stream<String>> strStrStrm = strArrStrm.map(Arrays::stream);
// 여러개의 문자열 배열을 -> 하나의 문자열 배열로 바꾸고자 할때
{"..",".."},{"..",".."} 이런 배열을
"..", "..", "..", ".." 이렇게 바꿀때
// flatMap() 을 이용!
Stream<String> strStrStrm = strArrStrm.flatmap(Arrays::stream);
스트림의 연산 - 최종연산
foreach()
- 스트림의 요소를 소모하는 최종연산
- 출력하는 용도로 많이 씀
allMatch(), anyMatch(), noneMatch()
- 스트림의 요소에 의해 지정된 조건에 모든 요소가 일치하는 지
- allMatch() : 모두 만족하는지
- anyMatch() : 하나라도 만족하는지
- noneMatch() : 모두 만족하지 않는지
findFirst(), findAny()
- findFirst() : 스트림의 요소 중 첫번째로 조건을 만족하는 값 반환
- findAny() : 스트림의 요소 중 조건을 만족하는 것 중 아무거나 반환
count(), sum(), average(), max(), min()
- 스트림의 요소에 대한 통계정보를 얻음
- 요소 총 수, 합, 평균, 최대값, 최소값
reduce()
- 스트림의 요소를 줄여나가면서 연산을 수행하고 최종결과 반환
출처
자바의 정석