스트림 만들기
1. 컬렉션
- 컬렉션의 최고 조상인 Collection에 stream()이 정의되어 있으므로, Collection의 자손인 List와
Set을 구현한 컬렉션 클래스들은 모두 이 메서드로 스트림을 생성할 수 있다.
- stream()은 아래와 같이 해당 컬렉션을 소스로 하는 스트림을 반환한다.
Stream<T> Collection.stream()
2. 배열
- Stream과 Arrays에 static 메서드로 아래와 같이 정의되어 있다.
(1) Stream<T> Stream.of(T... values)
ex) Steam.of("a","b")
//가변인자
(2) Stream<T> Stream.of(T[])
ex) Stream.of(new String[] {"a","b"})
(3) Stream<T> Arrays.stream(T[])
ex) Arrays.stream(new String[] {"a","b"})
(4) Stream<T> Arrays.stream(T[] array, int startInclusive, int endExclusive)
ex) Arrays.stream(new String[] {"a","b"}, 0, 2)
( (1),(2)에서 Stream 앞에 int, long, double을 둘 수 있다. )
( (3),(4)에서 매개변수 T를 대신하여 int, long, double을 대신할 수 있다. )
3. 특정 범위의 정수
- IntStream과 LongStream은 지정된 범위의 연속된 정수를 스트림으로 생성해서 반환하는
아래와 같은 range()와 rangeClosed()가 있다.
(1) IntStream.range(int begin, int end)
ex) IntStream.range(1,5)
// 1,2,3,4 출력
(2) IntStream.rangeClosed(int begin, int end)
ex) IntStream.rangeClosed(1,5)
// 1,2,3,4,5 출력
4. 임의의 수
- 난수를 생성하는 Random 클래스에는 아래와 같은 인스턴스 메서드들이 포함되어 있다.
(1) IntStream ints()
(2) LongStream longs()
(3) DoubleStream doubles()
( 이 메서드들이 반환하는 스트림은 크기가 정해지지 않은 '무한 스트림'이다. )
( 그러므로, limit()와 같이 써서 아래와 같이 크기를 제한해야 한다. )
IntStream intStream = new Random().ints(5);
// 5개 요소만 출력한다.
intStream.limit(5).forEach(System.out::println)
// 5개 요소만 출력한다.
IntStream intStream = new Random().ints(1, 46).distinct().limit(6);
// 1~46 사이의 숫자 중에 6개 요소만 출력한다.
( 또한 (1), (2), (3) 함수 뿐만 아니라 매개변수가 여러 개 있는 아래와 같은 오버로딩된
메서드가 있다. )
(int begin, int end)
(long streamSize, int begin, int end)
5. 람다식 - iterate(), generate()
- iterate()와 generate()는 람다식을 매개변수로 받아서 아래와 같이 요소로 하는 무한 스트림을
생성한다.
(1) Static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
(2) Static <T> Stream<T> generate(Supplier<T> s)
- iterate()는 seed로 지정된 값부터 시작해서, 람다식 f에 의해 반복해서 아래와 같이 계산한다.
Stream<Integer> eventStream = Stream.iterate(0, n->n+2)
// 0, 2, 4, 6 ... 출력
- generate() 또한 위와 같이 반복 계산을 하지만, iterate()와 달리 이전 결과를 이용해서 다음 요소를
계산하지 않는다.
- generate()는 매개변수가 Supplier<T> 이므로 매개변수가 없는 람다식만 사용할 수 있다.
- 주의할 점은 iterate()와 generate() 둘 다 기본형 스트림 타입을 다룰 수 없다.
( 만약 다루게 되면, 에러가 발생한다. )
( 꼭 다루어야 된다면, 864~865p에 있는 변환 방법을 참고한다. )
6. 파일
- java.nio.file.Files는 파일을 다루는데 필요한 유용한 메서드들을 제공한다.
- list()는 지정된 디렉토리에 있는 파일의 목록을 소스로 하는 스트림을 생성해서 반환한다.
Stream<Path> Files.list(Path dir)
// 이때, Path는 하나의 파일 또는 경로를 의미한다.
- 또한 파일의 한 행을 요소로 하는 스트림을 생성하는 아래와 같은 메서드도 있다.
(1) Stream<String> Files.lines(Path path)
(2) Stream<String> Files.lines(Path path, Charset cs)
(3) Stream<String> lines()
// Buffereder 클래스의 메서드이다.
7. 빈 스트림
- 요소가 하나도 없는 비어있는 스트림을 생성할 수도 있다.
- null보다 빈 스트림을 반환하는 것이 좋기 때문에 아래와 같이 사용한다.
Stream emptyStream = Stream.empty()
long count = emptyStream.count()
// count()는 0을 반환한다.
8. 두 스트림의 연결
- Stream의 static 메서드인 concat()을 사용하면 두 스트림을 하나로 연결할 수 있다.
( 두 스트림의 요소가 같은 타입이면 가능하다. )