14-15~16 스트림, 스트림의 특징
- CF(컬렉션 프레임워크) : List, Set, Map 사용방법이 달라서 사실상 표준화 실패(반쪽짜리 표준화)
스트림(Stream)
- 다양한 데이터 소스(컬렉션, 배열)를 표준화된 방법으로 다루기 위한 것(JDK 1.8)
- 스트림 생성 방법
Stream<T> Collection stream()
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);
// 난수 스트림(크기가 5)
IntStream intStream = new Random().ints(5);
- 데이터 소스 -> Stream -> 중간 연산(n번) -> 최종 연산(1번) -> 결과
- 스트림 만들기
- 중간 연산(0 ~ n번)
- 최종 연산(0 ~ 1번)
스트림이 제공하는 기능 - 중간 연산, 최종 연산
- 중간 연산 : 연산 결과가 스트림인 연산. 반복적으로 적용 가능
- 최종 연산 : 연산 결과가 스트림이 아닌 연산. 단 한 번만 적용 가능(스트림의 요소를 소모)
String[] strArr = {"dd", "aaa", "CC", "cc", "b"};
// 1. 문자열 배열이 소스인 스트림 생성
Stream<String> stream = Stream.of(strArr);
// 2. 중간 연산
Stream<String> filteredStream = stream.filter(); // 걸러내기
Stream<String> distinctedStream = stream.distinct(); // 중복 제거
Stream<String> sortedStream = stream.sort(); // 정렬
Stream<String> limitedStream = stream.limit(5); // 스트림 자르기
// 3. 최종 연산
int total = stream.count(); // 요소 개수 세기
스트림의 특징
- 스트림은 데이터 소스로부터 데이터를 읽기만할 뿐(ReadOnly) 변경하지 않는다.
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.print(i + ",")); // 최종 연산
- 스트림은 작업을 내부 반복으로 처리한다.
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) // 내부 반복(for문을 메서드 안으로 넣음)
action.accept(T);
}
- 병렬 스트림 지원: 스트림의 작업을 병렬로 처리, 멀티 쓰레드로 병렬처리(빅데이터 처리)
Stream<String> strStream.of("dd", "aaa", "CC", "cc", "b");
int sum = strStream.parallel() // 병렬 스트림으로 전환(속성만 변경)
.mapToInt(s -> s.length()).sum(); // 모든 문자열의 길이의 합
- 성능 개선을 하고 싶을 때(빅데이터 처리) : 기본형 스트림 - IntStream, LongStream, DoubleStream 사용
- 오토박싱 & 언박싱의 비효율이 제거됨(Stream 대신 IntStream 사용)
- 숫자와 관련된 유용한 메서드를 Stream<'T'>보다 더 많이 제공
Author And Source
이 문제에 관하여(14-15~16 스트림, 스트림의 특징), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@oyeon/14-1516-스트림-스트림의-특징저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)