JAVA/스트림

스트림 만들기

chanhee01 2023. 8. 8. 21:33

스트림 만들기 - 컬렉션

 

Collection 인터페이스의 stream()을 이용해서 컬렉션을 스트림으로 변환

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> intStream = list.stream();

// 스트림의 모든 요소를 출력
intStream.forEach(System.out::print); // 12345
intStream.forEach(System.out::print); // 스트림이 닫혔기 때문에 에러

forEach는 최종연산이기 때문에 1번까지만 호출이 가능하다. 그래서 2번째 forEach에서는 에러가 난다.

 

 

intStream = list.stream();
intStream.forEach(System.out::println);

두 번째 forEach 전에 다시 스트림을 만들어주고 forEach를 하면 된다.

 

 

 

 

 

스트림 만들기 - 배열

Stream<String> strStream = stream.of("a", "b", "c");
Stream<String> strStream = stream.of(new String[]{"a", "b", "c"});
Stream<String> strStream = Arrays.stream(new String[]{"a", "b", "c"});
Stream<String> strStream = Arrays.stream(new String[]{"a", "b", "c"}, 0, 3);

위와 같은 4가지 방법으로 배열의 스트림을 만들 수 있다.

 

 

 

int[] intArr = {1,2,3,4,5};
IntStream intStream = Arrays.stream(intArr);
intStream.forEach(System.out::println);
System.out.println("count="+intStream.count());
System.out.println("sum="+intStream.sum());
System.out.println("average="+intStream.average());

stream은 많은 기능을 제공한다. forEach()로 출력, count(), sum(), average()를 수행할 수 있는데 방금 말한 4개 모두 최종 연산이기 때문에 하나를 제외하고는 주석처리를 해주거나 사이사이에 계속해서 스트림을 새로 만들어줘야 한다.

 

 

 

Stream<Integer>와 IntStream의 차이

Stream<Integer>는 사실 Stream<T>이다. 모든 타입을 받을 수 있는 스트림이기 때문에 IntStream처럼 숫자 스트림만 사용할 수 있는 sum(), average() 등은 제공하지 않는다.

따라서 기본형 타입의 스트림을 사용하는 것이 좋다.

 

 

 

 

 

스트림 만들기 - 임의의 수(난수)

IntStream intStream = new Random().ints();        // 무한 스트림
intStream.limit(5).forEach(System.out::println);  // 5개의 요소만 출력
        
IntStream intStream1 = new Random().ints(5);      // 크기가 5인 난수 스트림을 반환

 

 

지정된 범위의 난수를 요소로 갖는 스트림

IntStream intStream = Random().ints(int begin, int end) // 무한 스트림

IntStream intStream1 = Random().ints(long StreamSize, int begin, int end) // 유한 스트림

만약에

IntStream intStream = Random().ints(10, 5, 10); // 5 ~ 10이 아니라 5 ~ 9까지이다.

이라는 코드가 있으면 5부터 9까지 10개의 난수를 생성하는 것이다.

 

 

 

 

 

스트림 만들기 - 특정 범위의 정수

IntStream intStream = IntStream.range(1, 5);       // 1, 2, 3, 4
IntStream intStream = IntStream.rangeClosed(1, 5); // 1, 2, 3, 4, 5

range를 통해 범위를 만들 수 있다.

파라미터가 (int begin, int end)일 때 range는 end를 포함하지 않고 rangeClosed는 end를 포함해서 범위를 설정한다.

 

 

 

 

스트림 만들기 - 람다식 iterate(), generate()

Stream<Integer> evenStream = Stream.iterate(0, n -> n+2);

iterate()는 이전 요소를 seed로 해서 다음 요소를 계산한다.

iterate()안의 첫 번째 값(0)은 초기 값(seed)이며 초기값이 람다식을 무한으로 수행하게 된다. 무한스트림이며 스트림은 0, 2, 4, 6 ....으로 진행된다.

 

Stream<Double>  randomStream = Stream.generate(Math::random);
Stream<Integer> oneStream    = Stream.generate(() -> 1);

generate()는 seed를 사용하지 않는다. 위의 코드는 계속 난수를 생성해내고, 밑의 코드는 계속 1을 만들어내는 것이다.

 

 

둘 다 무한 스트림이기 때문에 스트림을 만들고 사용할 때는 원하는 만큼 limit를 걸어주면 된다.

intStream.limit(10).forEach(System.out::println);

스트림 이름이 intStream이라 가정했을 때 이렇게 limit를 걸면 된다.

 

 

 

 

스트림 만들기 - 파일

Stream<Path> Files.list(Path dir) // Path는 파일 또는 디렉토리를 입력

파일들을 이렇게 스트림으로 받아올 수 있다.

 

 

Stream<String> Files.lines(Path path)
Stream<String> Files.lines(Path path, Charset cs)
Stream<String> lines()

파일을 가져온 다음 파일의 내용을 한 줄씩 읽어서 스트림을 만들 수도 있다.