crone 2021. 7. 21. 12:29

 collection들의 사용방법이 같지 않았다.map, set, list
jdk1.8 부터는 스트림이 나오며 표준화된 방법으로 데이터를 다룰 수 있다.
다양한 데이터 소스를 표준화된 방법으로 다루기 위한 것

데이터소스로부터 stream을 만들 수 있다. 스트림을 만들고 나면
같은 작업으로 처리를 하게 된다.
작업종류는 ->중간연산(n번) 최종연산(1번)

List<Integer> list  Arrays.sList(1,2,3,4,5);
Stream<Integer> intStream list.stream(); //collection
Stream<String> strStream Stream.of(new String[] {"a", "b", "c"}); //array
Stream<Integer> evenStream Stream.iterater(0, n->n+2); // 0, 2, 4, ...
Steam<Double> randomStream Stream.generate(Math::random) // lambda
IntStream intStream new Random().ints(5) //난수스트림 (size 5)

 

중간 연산과 최종 연산
중간 연산 -> 연산결과가 스트림인 연산. 반복적으로 적용가능 :: 0 ~ n번
최종 연산 -> 연산결과가 스트림이 아닌 연산. 단 한번만 적용하능(스트림의 요소를 소모) :: 0 ~ 1번

            중복제거, 5개자르기, 정렬          출력
ex) stream.distinct().limit(5).sorted().forEach(System.out::println)

 

스트림의 특징

스트림은 데이터 소스로부터 데이터를 읽기만할 뿐 변경하지 않는다.
원본은 그대로이고 원본에서 변환된 데이터를 얻을 수 있다.
List<Integer> list = Arrays.asList(3,1,5,4,2);
List<INteger> sortedList = list.stream().sorted().collect(Collectors.toList());

스트림은 Iterator처럼 일회용이다.(필요하면 다시 스트림을 생성해야 함)
strStream.forEach(System.out::println); //최종연산 (스트림의 요소를 소모)
int numOfStr = strStream.count() //error 스트림이 이미 닫혔음


최종 연산 전까지 중간연산이 수행되지 않는다 -> 지연된 연산
IntStream intStream = new Random().ints(1, 46) // 1~45범위의 무한 스트림 
intStream.distinct().limit(6).sorted().forEach(i -> System.out.print(i + ", ")) 


스트림의 특징

스트림은 작업을 내부 반복으로 처리한다.
for(String str : strList) System.out.println(str);
stream.forEach(System.out::println); //성능은 비효율적이지만 코드가 간결해 진다.

스트림의 작업을 병렬로 처리 - 병렬스트림 (parallel() <-> Sequential()(default) )
Stream<String> strStream = Stream.of("dd", "aaa", "CC", "cc", "b");
int sum = strStream.parallel().mapToInt(s -> s.length()).sum())


기본형 스트림 
IntStream, LongStream, DoubleStream...
오토박싱& 언박싱의 비효율이 제거됨(Stram<Integer> 대신 IntStream사용)
숫자와 관련된 유용한 메서드를 Stream<T>보다 더 많이 제공한다.

 

스트림 만들기 - collection
Stream<E> stream();

스트림 만들기 - 배열
Stream<T> Stream.of(T....values) -> Stream.of("a", "b", "c")
Stream<T> Stream.of(T[]) -> Stream.of(new String[] {"a", "b", "c"});
Stream<T> Arrays.stream(T[]) -> Arrays.stream(new String[]{"a", "b", "c"})
Stream<T> Arrays.stream(T[] array, int startInclusive, int endExclusive) // 3 ~ 8 // 3 ~ 7 까지
-> Arrays.stream(new String[] {"a", "c", "c"}, 0 , 3);

스트림 만들기 - 임의의 수
난수를 요소로 갖는 스트림 생성하기
IntStream intStream = new random().ints(); // 무한스트림
intStream.limit(5).forEach(System.out::print); //5개의 요소만 출력한다

IntStream intStream = new Random().ints(5); //크기가 5인 난수 스트림을 반환

스트림 만들기 - 파일과 빈 스트림
Stream<Path> files.list(Path.dir) //Path는 파일 또는 디렉토리 dir(폴더)
Stream<String> Files.lines(Path path) // 파일내용을 라인 단위로 읽는다 //log 또는 다량의 파일
Stream<String> Files.lines(Path path, Charset cs);
Stream<String> lines() // BufferedReader 클래스의 메소드


스트림의 연산 - 중간 연산

distinct() 중복을 제거
filter(Predicate<T> predicate) 조건에 안 맞는 요소 제외
limit(long maxSize) 스트림의 일부를 잘라낸다.
skip(long n) 스트림의 일부를 건너뛴다
peek(Consumer<T> action) 스트림의 요소에 작업수행 (중간에 확인할 때)
Stream<T> sorted()
Stream<T> sorted(Comparator<T> comparator)
스트림의 요소를 정렬한다.
map() 스트림의 요소를 변환한다.
flatMap()
 

 

스트림의 연산 - 최종연산

forEach(Consumer<? super T> action)
forEachEachordered(Consumer<? super T> action)
-> 순서유지, 병렬스트림때 사용한다.
각 요소에 지정된 작업 수행
long count() 스트림의 요소의 개수 반환
Optional<T> max (Comparator<? super ?> comparator)
min
스트림의 최대값/ 최소값을 반환
Optional<T> findAny() -> 병렬
Optional<T> findFirst() -> 직렬
스트림의 요소 하나를 반환 (filter와 같이 쓰임)
boolean allMatch(Predicate<T> p) //모두 만족하는지
boolean anyMatch(predicate<T> p) // 하나라도 만족하는지
boolean noneMatch(Predicate<T> p) // 모두 만족하지 않는지
주어진 조건을 모든 요소가 만족시키는지, 만족시키지 않는지 확인
Object[] toArray()
A[] toArray(IntFunction<A[]> generator) //특정 타입으로 반환
스트림의 모든 요소를 배열로 반환
Optional<T> reduce(BinaryOperator<T> accumnulator)
T reduce(T identity, BinaryOperator<T> accumnulator)
U reduce(U identity, BiFunction<U, T, U> accumnulator,
Binaryoperator<U> combiner)
스트림의 요소를 하나씩 줄여가면서 (리듀싱) 계산한다.
R collect(Collector<T ,A, R> collector)
R collect(Supplier<R> supplier, BiConsumer<R, T> accumnulator, biConsummer<R, R> combiner)
스트림의 요소를 수집한다
주로 요소를 그룹화하거나 분할한 결과를 컬렉션에 담아 반환하는데 사용한다.