다음 내용은 남궁성의 정석코딩 스트림편 을 보며 참고하여 정리한 내용입니다.
다양한 데이터 소스를 표준화된 방법으로 다루기 위한 것입니다.
배열이나 컬렉션 프레임워크 List, set, map로부터 straem을 만들어서 같은 방식으로 작업
List<Integer> list = Arrays.asList(1,2,3,4,5);
Stream<Integer> intStream = list.stream();
Stream<String> strStream = Stream.of(new String[]{'a','b'};
Stream<Integer> evenStream = Stream.iterate(0, n -> n+2)
Stream<Integer> ramdomStream = Stream.generate(Math::ramdom);
IntStream intStream = new Ramdom().ints(5);
스트림 연산 과정 : 스트림 생성 → 중간작업 (0~n번) → 최종작업(0~1번)
데이터의 연속적인 흐름으로 만들어서 한개 한개씩 중간 작업해주고 최종작업을 합니다.
중간 연산 : 연산 결과가 스트림인 연산, 반복적으로 적용 가능
최종연산 : 연산 결과가 스트림이 아닌 연산, 단 한번만 적용 가능(스트림의 요소를 소모)
ex)
stream.distinct().limit(5).sorted().forEach(System.out::println)
중간연산 <- -> 최종
List<Integer> list = Arrays.asList(4,1,2,3);
List<Integer> sortlist = list.stream().sorted()
.collect(Collectors.toList);
sout(list); // 4,1,2,3
sout(sortList); // 1,2,3,
strStream.forEach(System.out::println); //모든 요소를 출력(최종연산)
int numOfStr = strStream.count(); //에러
IntStream intStream = new Ramdom().ints(1,46)
IntStream.distinct().limit(6).sorted()
.forEach(i -> sout(i+",")
Stream<String> strStream = Stream.of("dd","aaa")
int sum = strStream.parallel() //병렬 스트림으로 전환(속성만 변경)
.mapToInt(s -> s.length()).sum; //모든 문자열 길이의 합
{1,2,3} 같은 기본형 데이터를 스트림에 저장하려면
1 → new Integer(1) 처럼 기본형을 참조형으로 변환하여 저장하게 되고 이를 오토박싱이라고 한다.
참조형으로 저장한 1을 다시 연산에 사용하려면 다시 1로 변환하는 과정이 필요한데 이를 언박싱이라고 하며 기본형 스트림은 오토박싱, 언박싱의 비효율을 제거해준다.
List<Integer> list = Arrays.asList(1,2,3,4,5);
Stream<Integer> intStream = list.stream(); // list를 스트림으로 변환
// 스트림의 모든 요소를 출력
intStream.forEach(System.out::print) // 12345
intStream.forEach(System.out::print) // 이미 닫힌 스트림
Stream<T> Stream.of(T...values)
Stream<T> Stream.of(T[])
Stream<T> Arrays.stream(T[])
// 기본형 배열로부터 스트림 생성
IntStream IntStrem.of(int...values)
IntStream IntStrem(int[])
IntStream intStream = new Random().ints(); //무한 스트림
intStream.limit(5).forEach(System.out::println); //리미트가 없으면 무한대로 출력
IntStream intStream = new Ramdom().ints(5); // 지정된 범위의 난수
Intstream intStream = IntStream.range(int begin, int end);
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f) // 이전 요소에 종속적
static <T> Stream<T> generate(Supplier<T> s) // 이전 요소에 독립적
iterate()는 이전 요소를 seed로 해서 다음 요소를 계산한다.
Stream<Integer> evenStream = Stream.iterate(0, n → n+2)
generate()는 seed를 사용하지 않는다.
Stream<Double> randomStream = Stream.generate(Math::random)
Stream<Integer> oneStream = Stream.generate(()->1);
연산 결과가 스트림인 연산, 즉 중간 연산을 거쳐도 여전히 스트림인 상태
중간연산 | 설명 |
---|---|
Stream distinct() | 중복을 제거 |
Stream filter(Predicate predicate) | 조건에 안 맞는 요소 제외( 맞는 것만 남겨둠) |
Stream skip(long n) | 일부를 잘라냄 |
Stream peek(Consumer action) | 요소에 작업 수행 (중간에 처리 결과 확인) |
| Stream sorted()
Stream sorted(Comparator comparator) | 요소를 정렬 |
| Stream map(Function<T,R> mapper
DoubleStream mapToDouble(ToDoubleFunction mapper
IntStream mapToInt(ToIntFunction mapper
LongStream mapToLong(ToLongFunction mapper | 요소를 변환한다. |
| Stream flatMap(Function<T,Stream> mapper>
DoubleStream flatMapToDouble(Function<T, DoubleStream>m)
IntStream flatMapToInt(Function<T, IntStream> m)
LongStream flatMapToLong(Function<T, LongStream> m) | 요소를 변환한다. |
map() : 요소 변환
flatmap() : 스트림의 스트림 → 스트림으로