본문 바로가기
JAVA

Java Stream 생성하기

by 봄석 2019. 9. 1.

Java Stream 생성하기

 

1. 생성하기

  • 배열 , 컬렉션, 빈스트림
  • Stream.builder() , Stream.generate() , Stream.iterate()
  • 기본타입형 , String , 파일스트림
  • 병렬스트림, 스트림연결하기

 

 

배열스트림 , 컬렉션스트림 생성하기

스트림은 배열 또는 컬렉션 인스턴스를 이용하여 생성할 수 있습니다 .

Arrays.stream이나 Collection.stream()메소드를 사용합니다.

//array
String[] arr = new String[]{"a", "b", "c"};
Stream<String> stream = Arrays.stream(arr);
Stream<String> streamOfArrayPart = Arrays.stream(arr, 1, 3); // 1~2 요소 [b,c]
//collection
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
Stream<String> parallelStream = list.parallelStream(); // 병렬 처리 스트림

 

비어있는 스트림

비어 있는 스트림(empty streams)도 생성할 수 있습니다

public Stream<String> streamOf(List<String> list) {
        return list == null || list.isEmpty()
                ? Stream.empty()
                : list.stream();
}

 

 

스트림빌더

Builder(빌더)를 사용하면 스트림에 직접적으로 원하는 값을 넣을 수 있습니다.

마지막에 build()메소드를 호출하여 스트림을 리턴합니다.

 Stream<String> builderStream =
                Stream.<String>builder()
                        .add("Eric")
                        .add("Elena")
                        .add("Java")
                        .build(); // [Eric, Elena, Java]

 

 

스트림제너레이터

generate 메소드를 이용하면 Supplier<T>에 해당하는 람다로 값을 넣을 수 있습니다.

Supplier<T>는 인자는 없고 리턴값만 있는 함수형 인터페이스 입니다. 람다에서 리턴하는 값이 들어갑니다.

public static<T> Stream<T> generate(Supplier<T> s) { ... }

 

이때 생성되는 스트림은 크기가 무한하기때문에 , limit(int)를 호출하여 특정 사이즈로 최대 크기를 제한해 주어야 합니다.

Stream<String> generatedStream = Stream.generate(() -> "next").limit(5);
        return generatedStream;

 

스트림이터레이터

iterate메소드를 이용하면 초기값과 해당 값을 다루는 람다를 이용해서 스트림에 들어갈 요소를 만듭니다.

Stream<Integer> streamIterator = Stream.iterate(0, a -> a + 2).limit(10);

0부터 시작해서 2씩 10번 더하게 됩니다.

 

 

기본타입형 스트림

제네릭을 이용하여 타입 스트림을 생성할 수 있지만 , 직접적으로 해당 타입의 스트림을 다룰 수도 있습니다.

public IntStream generateIntStream() {
        IntStream is = IntStream.range(1, 5);
        //1,2,3,4
        return is;
    }

    public LongStream generateLongStream() {
        LongStream ls = LongStream.rangeClosed(1, 5);
        //1,2,3,4,5
        return ls;
    }

    public void generateRandomStream() {
        DoubleStream ds = new Random().doubles(3);
        IntStream is = new Random().ints(3);
        LongStream ls = new Random().longs(3);
        // 난수 3개 생성, double, int, long 가능
    }

range와 rangeClosed는 범위의 차이입니다.

random클래스를 이용하여 (Intstream,LongStream,DoubleStream)을 만들어 낼 수 있습니다.

쉽게 난수 스트림을 생성하여 여러가지 후속 작업을 취할 수 있습니다.

 

직접적으로 해당 타입의 스트림을 만들면, 제네릭을 사용하지 않기 때문에  

불필요한 오토박식(auto-boxing)이 일어나지 않습니다.

boxed메소드를 이용하여 박싱처리를 할 수 있습니다.

Stream<Integer> boxedIntStream = IntStream.range(1, 5).boxed();

 

 

문자열 스트림

스트링을 이용해서 스트림을 생성할수도 있습니다.

정규표현식을 이용하여 문자열을 자르고 , 각 요소들로 스트림을 만든 간단한 예입니다.

//        다음은 정규표현식(RegEx)을 이용해서 문자열을 자르고, 각 요소들로 스트림을 만든 예제입니다.
        Stream<String> stringStream =
                Pattern.compile(", ").splitAsStream("Eric, Elena, Java");
        // [Eric, Elena, Java]

 

 

파일 스트림

자바 NIO의 Files 클래스의 lines  메소드는 각 해당 파일의 라인을 스트링 타입의 스트림으로 만들어 줍니다.

 //자바 NIO 의 Files 클래스의 lines 메소드는 해당 파일의 각 라인을 스트링 타입의 스트림으로 만들어줍니다.
        try {
            Stream<String> lineStream =
                    Files.lines(Paths.get("file.txt"),
                            Charset.forName("UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }

 

병렬스트림

스트림 생성 시 사용하는 stream 대신 parallelStream 메소드를 사용해서 병렬 스트림을 쉽게 생성할 수 있습니다.

내부적으로는 스레드를 처리하기 위해서 java 7부터 도입된 Fork/ Join framwork를 사용합니다.

 

public class ParallelStream {
    String[] sa = new String[]{"1", "2"};

    public void generateParallelStream() {
        // 병렬 스트림 생성
        Stream<String> parallelStream = Arrays.asList(sa).parallelStream();

        // 병렬 여부 확인
        boolean isParallel = parallelStream.isParallel();
    }

    public void generateFromArrayToParallelStream() {
    	//배열을 이용하여 병렬 스트림 생성
        Arrays.stream(sa).parallel();
    }

    public void generateNotCollectionAndArrayParallelStream() {
	    //컬렉션과 배열이 아닌 경우는 다음과 같이 parallel 메소드를 이용해서 처리합니다.
        IntStream intStream = IntStream.range(1, 150).parallel();
        boolean isParallel = intStream.isParallel();
    }

    public void parallelToSequentialStream() {
    	//다시 시퀀셜(sequential) 모드로 돌리고 싶다면 다음처럼 sequential 메소드를 사용합니다
        IntStream intStream = IntStream.range(1, 150).sequential();
        boolean isParallel = intStream.isParallel();
    }
}

 

 

스트림 가공하기

concat을 이용하여 스트림을 순서대로 연결하고 , 새로운 스트림을 만들어 낼 수도 있습니다.

Stream<String> stream1 = Stream.of("Java", "Scala", "Groovy");
        Stream<String> stream2 = Stream.of("Python", "Go", "Swift");
        Stream<String> concat = Stream.concat(stream1, stream2);
        // [Java, Scala, Groovy, Python, Go, Swift]

'JAVA' 카테고리의 다른 글

Java - 메모리관리 ( 스택& 힙) [펌]  (0) 2019.09.01
Primitive vs Reference  (0) 2019.09.01
Java Stream 결과 만들기  (0) 2019.09.01
Java Stream 가공하기  (0) 2019.09.01
Java Stream알아보기  (0) 2019.09.01

댓글