상세 컨텐츠

본문 제목

[Java] 9. 다양한 Stream의 생성

프로그래밍 언어/Java(자바)

by Guroo 2023. 9. 13. 16:29

본문

[Java] 8. Stream의 개념과 사용 방법-1

 

[Java] 8. Stream의 개념과 사용 방법-1

[Java] 7. 메소드 참조 (::) [Java] 7. 메소드 참조 (::) 6. Map에 정의된 추상 메소드와 default 메소드 6. Map에 정의된 추상 메소드와 default 메소드 6-1. Map에 정의된 추상 메소드와 default 메소드 이번에 살펴

sesoc.tistory.com

 

https://www.ifourtechnolab.com/blog/a-guide-on-java-stream-api

이전 스토리에서는 스트림을 생성하고 해당 스트림으로 중간연산, 최종연산을 하는 방법에 대해서 간단히 알아보았다.

 

지난 스토리에 이어서 이번에도 Stream의 생성 방법과 간단한 중간연산을 다시 한번 확인해보도록 하자.

 

9-1. Stream의 생성방법

1) Collection으로부터 Stream을 생성

Stream<String> stream1 = list.stream();
Stream<String> stream2 = set.stream();

 

 

2) int, long, double형 배열로부터 Stream 생성

IntStream sInt = Arrays.stream(int형 배열);
LongStream sLong = Arrays.stream(long형 배열);
DoubleStream sDouble = Arrays.stream(double형 배열);

*** 예

IntStream sInt = Arrays.stream(new int[] {1, 2, 3, 4, 5});
LongStream sLong = Arrays.stream(new long[] {1, 2, 3, 4, 5});
DoubleStream sDouble = Arrays.stream(new double[] {1.0, 2.2, 3.5, 4.6, 5.2});

 

3) Stream.iterate() 메소드를 이용한 Stream의 생성

주의할 것은 iterate() 메소드를 사용해서 생성된 스트림은 무한 스트림이라는 것이다.

무한 스트림이라는 것은 말 그대로 무한히 계속해서 값을 생산해 내는 스트림이라는 것으로 iterate() 메소드와 이후 예제로 살펴볼 generate() 메소드도 역시 무한 스트림이므로 발생된 스트림 값을 한정시켜주어야 한다는 것을 잊어서는 안된다.

 

Stream.iterate(T seed, UnaryOperator<T> f);

 

** 무한 스트림의 생성 예

Stream.iterate(2, x->x+2).forEach(System.out::println);

 

이 코드를 실행하면 첫 번째 인자로 주어진 숫자 2를 초기값으로 하여 2씩 증가하는 무한 스트림을 생성한다. 이 스트림을 출력하면 무한 루프에 빠진 것처럼 무한히 반복되어 출력된다.

 

그러므로 iterate()로 생성한 메소드는 개수를 한정시킬 수 있는 limit()라는 메소드와 함께 사용해야 한다.

 

** 2부터 시작하여 2씩 증가하는 값을 10

Stream.iterate(2, x->x+2)
    .limit(10)
    .forEach(System.out::println);

 

IteratemethodTest.java

import java.util.stream.Stream;

public class IterateMethodTest {
    public static void main(String[] args) {
        // 3의 배수 10개
        System.out.println("------ [ 3의 배수 ] ------");
        Stream.iterate(3, (x) -> x + 3)
            .limit(10)
            .forEach(System.out::println);
        
        System.out.println("------ [ 5의 배수이거나 8의 배수 ] ------");
        // 10개 중 앞 2개는 건너뛰고 8개만 스트림으로 생성
        Stream.iterate(1, x -> ++x)
            .filter(x -> x%5 == 0 || x%8 ==0? true: false)
            .limit(10)
            .skip(2)
            .forEach(System.out::println);
    }
}

 

실행 결과

------ [ 3의 배수 ] ------
3
6
9
12
15
18
21
24
27
30
------ [ 5의 배수이거나 8의 배수 ] ------
10
15
16
20
24
25
30
32

 

4) Stream.generate() 메소드를 이용한 Stream의 생성

generate() 메소드도 위에서 살펴본 iterate()와 유사하다. 전달할 Lambda식은 Supplier 타입이므로 값을 발생시키는 Math.random() 이나 Random클래스의 난수 발생 메소드와 함께 사용할 때 유용하다.

 

이 메소드도 무한 스트림이다.

 

static <T> Stream<T> generate(Supplier<T> s)

 

** 1~100사이의 난수를 무한 발생하는 예

Stream.generate(() -> (int)(Math.random() * 100 + 1)).forEach(System.out::println);

 

GenerateMethodTest.java

import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class GenerateMethodTest {
    public static void main(String[] args) {
        Random random = new Random();

        // 1) 중복되지 않는 로또 번호 5개 발생
        System.out.println("------ [ 난수 5개 발생 ] ------");
        Stream.generate(() -> random.nextInt(45)+1)
            .limit(5)
            .collect(Collectors.toSet())
            .forEach((x)->System.out.print(x+" "));
       
        System.out.println();
        
        // 2) 임의의 알파벳 10개 발생
        System.out.println("------ [ 알파벳 10개 발생 ] ------");
        Stream.generate(() -> (char)(random.nextInt(26) + 'a'))
            .limit(10)
            .forEach(System.out::println);
        
        // 3) 1~100사이의 3배수를 난수발생 시키되, 중복되지 않도록 한다.
        //    Math 클래스의 static 메소드인 random()을 사용할 것.
        System.out.println("------ [ 중복되지 않는 3의 배수 발생 ] ------");
        
        Stream.generate(() -> (int)(Math.random() * 100 + 1))
            .filter(x -> x%3 == 0 ? true:false)
            .limit(10)
            .collect(Collectors.toSet())
            .forEach(System.out::println);
    }
}

 

** 실행 결과

------ [ 난수 5개 발생 ] ------
18 41 42 30 15 

------ [ 알파벳 10개 발생 ] ------
x
o
b
x
q
u
q
x
r
o

------ [ 중복되지 않는 3의 배수 발생 ] ------
48
99
84
69
87
72
42
60
30
15

 

 

 

이번에 살펴본 스트림 관련 메소드는 주로 생성에 관한 것들이었다.

중간연산과, 최종 연산에 관한 내용은 다음에 다시 살펴보도록 하자.

 


이전 글: [Java] 8. Stream의 개념과 사용 방법-1

 

관련글 더보기

댓글 영역