스트림
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) |
스트림의 요소를 수집한다 주로 요소를 그룹화하거나 분할한 결과를 컬렉션에 담아 반환하는데 사용한다. |