컬렉션, 배열 등 데이터 소스에 따라 Stream<T>
를 생성하는 방법을 정리해둔다.
stream()
메서드를 호출해서 생성한다. 컬렉션의 최고 조상인 Collection에 stream()
메서드가 정의되어 있으므로 모든 컬렉션 클래스들은 .stream()
으로 스트림을 만들 수 있다.
Stream 클래스의 of()
메서드나 Arrays 클래스의 stream()
으로 생성한다.
of()
와 stream()
메서드는 static 메서드이므로 아래와 같이 사용한다.
Stream<String> stringStream1 = Stream.of("aaa", "bbb", "ccc");
Stream<String> stringStream2 = Arrays.stream(new String[] {"aaa", "bbb", "ccc"});
특정 범위의 연속된 정수 스트림을 만드는 방법은 아래와 같다.
IntStream intStream = IntStream.range(1, 5); // 5 포함 x
IntStream intStream = IntStream.rangeClosed(1, 5); // 5 포함
난수 스트림을 만드는 방법은 아래와 같다.
IntStream intStream = new Random().ints(수의 갯수, 시작 수, 끝 수); // 끝 수는 포함x
LongStream longStream = new Random().longs(5, 1, 10);
DoubleStream doubleStream = new Random().doubles(5, 1.0, 5.0);
람다식을 매개변수로 스트림을 생성할 수 있는 방법은 2가지가 있다. 하지만 둘 다 기본형 스트림 타입(IntStream 등)의 참조변수로는 다룰 수 없다.
1) iterate()
seed 값으로 지정된 값으로 시작해서 람다식에 의해 계산된 결과를 seed 값으로 하여 계산을 반복하고 seed 값들로 스트림을 형성한다.
Stream<T> stream = Stream.iterate(seed값, 람다식);
Stream<Integer> evenStream = Stream.iterate(0, n -> n + 2); // 0, 2, 4, 6, ...
2) generate()
iterate()은 이전 결과를 이용해서 다음 요소를 계산하지만, generate()은 이전 결과를 이용해서 다음 요소를 계산하지 않는다.
매개변수가 없는 람다식만 매개변수로 허용된다.
Stream<Integer> randomStream = Stream.generate(Math::random);
연산 수행 결과가 없는 경우 null보다 빈 스트림을 반환하는 것이 좋으므로 아래와 같이 빈 스트림을 만든다.
Stream emptyStream = Stream.empty();
같은 타입의 2개의 스트림을 하나의 스트림으로 합칠 수 있다.
Stream<String> stream1 = Stream.of("a", "b", "c");
Stream<String> stream2 = Stream.of("d", "e", "f");
Stream<String> stream3 = Stream.concat(stream1, stream2);