- 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);
Stream<Double> randomStream = Stream.generate(Math::random);
IntStream intStream = new Random().ints(5);
- 데이터 소스 -> Stream -> 중간 연산(n번) -> 최종 연산(1번) -> 결과
- 스트림 만들기
- 중간 연산(0 ~ n번)
- 최종 연산(0 ~ 1번)
스트림이 제공하는 기능 - 중간 연산, 최종 연산
- 중간 연산 : 연산 결과가 스트림인 연산. 반복적으로 적용 가능
- 최종 연산 : 연산 결과가 스트림이 아닌 연산. 단 한 번만 적용 가능(스트림의 요소를 소모)
String[] strArr = {"dd", "aaa", "CC", "cc", "b"};
Stream<String> stream = Stream.of(strArr);
Stream<String> filteredStream = stream.filter();
Stream<String> distinctedStream = stream.distinct();
Stream<String> sortedStream = stream.sort();
Stream<String> limitedStream = stream.limit(5);
int total = stream.count();
스트림의 특징
- 스트림은 데이터 소스로부터 데이터를 읽기만할 뿐(ReadOnly) 변경하지 않는다.
List<Integer> list = Arrays.asList(3, 1, 5, 4, 2);
List<Integer> sortedList = list.stream().sorted()
.collect(Collectors.toList());
System.out.println(list);
System.out.println(sortedList);
- 스트림은 Iterator처럼 일회용이다.(필요하면 다시 스트림을 생성해야 함)
strStream.forEach(System.out::println);
int numOfStr = strStream.count();
- 최종 연산전까지 중간 연산이 수행되지 않는다. - 지연된 연산
IntStream intStream = new Random().ints(1, 46);
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)
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'>보다 더 많이 제공