ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스트림
    java 2019. 1. 4. 21:38

    스트림

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.stream.IntStream;
     
    public class MyFirstStream {
        public static void main(String[] args) {
            int[]ar = {1,2,3,4,5};
            IntStream stm1 = Arrays.stream(ar); //배열 ar로 부터 스트림 생성
            IntStream stm2 = stm1.filter(n-> n%2 ==1); //중간 연산 진행
            int sum = stm2.sum();//최종연산
            System.out.println(sum);
            
        }
    }
     
    cs

    출이면 이렇게 됨

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.stream.IntStream;
     
    public class MyFirstStream {
        public static void main(String[] args) {
            int[]ar = {1,2,3,4,5};
            System.out.println( Arrays.stream(ar).filter(n-> n%2 ==1).sum());
            
        }
    }
     
    cs


    스트림(Stream)의 특성

    위 예제에서 호출하는 stream 과 filter 의 반환형은 Intstream이다.


    filter와 sum은 IntStream의 인스턴스 메소드 


    스트림생성하기 : 배열

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            String [] names = {"YOON","LEE","KIM"};
            Stream<String> stm = Arrays.stream(names);// 스트림 생성
            stm.forEach(s-> System.out.println(s));//최종 연산 진행
        }
    }
     
    cs

    forEach는 Iterable<T> 인터페이스에 정의되어있는 디폴트 메소드

    default void forEach(Cunsummer<? super T> action){

    for(T t : this) action.accept(t);

    }


    forEach : 람다식을 전달하면 내부적으로 스트림데이터를 하나씩 인자로 전달하면서 accept 메소드를 호출한다. 


    forEach는 최종연산임 
    중간연산없이 바로 최종연산도 가능하다 .
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            String [] names = {"YOON","LEE","KIM"};
            Arrays.stream(names)
                  .forEach(s-> System.out.println(s));// 스트림 생성
        }
    }
     
    cs
    In

    IntStream 에 매개변수로 그냥 배열을 넣으면 전부를 stream

    (배열 , 시작인덱스 , 끝인덱스)를넣으면 부분을 stream

    모두 Arrays 클래스에 정의 되어있음

    DoubleStream과  LongStream도 같다

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            double [] ds = {1.1,2.2,3.3,4.4,5.5};
            
            Arrays.stream(ds)
                   .forEach(d-> System.out.print(d+"\t"));
            System.out.println();
            
            Arrays.stream(ds,1,4//인덱스1 에서 4이전 까지
                   .forEach(d->System.out.print(d+"\t"));
            System.out.println();
        }
    }
     
    cs

    1.1 2.2 3.3 4.4 5.5

    2.2 3.3 4.4


    스트림 생성하기 : 컬렉션 인스턴스

     컬렉션 인스턴스를 대상으로도 스트림을 생성할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            List<String> list = Arrays.asList("TOy" , "robbot","box");
            list.stream()
                .forEach(s -> System.out.print(s+"\t"));
            System.out.println();
        }
    }
     
    cs


    필터링과 맵칭



    필터링

    필터링은 스트림을 구성하는 데이터중 조건에 따라 걸러내는 행위

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            List<String> list = Arrays.asList("TOy" , "robbot","box");
            list.stream()
                .filter(s -> s.length()==3)
                .forEach(s -> System.out.print(s+"\t"));
            System.out.println();
        }
    }
     
    cs

    문자 길이가 3이상이면 통과

    맵핑 1 

    맵핑릉하면 스트림의 데이터형이 달리지는 특징이 있음
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            List<String> list = Arrays.asList("TOy" , "robbot","box");
            list.stream()
                .map(s->s.length())
                .forEach(s -> System.out.print(s+"\t"));
            System.out.println();
        }
    }
     
    cs

    이 과정에서 변환후에 인자로 전달하기때문에 오토박싱이 일어남 

    그래서 기본자료형의 값을 봔환하는 경우를 고려하여 매핑관련 매소드를 제공하고있음

    mapToInt

    mapToLong

    mapToDouble

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            List<String> list = Arrays.asList("TOy" , "robbot","box");
            list.stream()
                .mapToInt(s->s.length())
                .forEach(s -> System.out.print(s+"\t"));
            System.out.println();
        }
    }
     
    cs


    리덕션(Reduction) ,병렬스트림(Paralel Stream)


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.BinaryOperator;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            List<String> ls = Arrays.asList("Box" , "Simple","Complex","Robot");
            
            //바이너리 오퍼레이터는 매개변수가 두개인 디폴트 인터페이스 
            BinaryOperator<String> lc = (s1,s2)->{
                if(s1.length() > s2.length()) {
                    return s1;
                }else {
                    return s2;
                }
            };
            String str  = ls.stream()
                    .reduce("",lc);
            
            System.out.println(str);
        }
    }
     
    cs

    Complex


    String str  = ls.stream()
                    .reduce("",lc);

    reduce는 내부적으로 스트림을 구성하는 문자열의 길이를 비교해 나감

    마지막에는 가장 긴 문자열을 반환하게 됨 

    reduce 메소드이 첫번째 인자로 전달되는 값은 스트림에 데이터가 하나도 없을때 반환된다 . 

    String str  = ls.stream()
                    .reduce("빈 스트림 일 경우이다 ",lc);

    라고 작성하면 첫번째 인자가 반환된다. 

    스트림이 비어있지 않은경우에는  이를 첫번째 데이터로 간주하고

    리덕션을 진행한다.

    이러한 특성은 리덕션했을때 조건에 충족하는 적당한 값이 없을때 대신할 데이터로서 지정할 수 있다..


    병렬 스트림

    하나의 작업을 둘 이상의 작업으로 나누어 진행 을 병렬처리라고 함 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.BinaryOperator;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            List<String> ls = Arrays.asList("Box" , "Simple","Complex","Robot");
            
            //바이너리 오퍼레이터는 매개변수가 두개인 디폴트 인터페이스 
            BinaryOperator<String> lc = (s1,s2)->{
                if(s1.length() > s2.length()) {
                    return s1;
                }else {
                    return s2;
                }
            };
            String str  = ls.parallelStream()
                    .reduce("",lc);
            
            System.out.println(str);
        }
    }
     
    cs

    차이는 스트림에서 하는 연산을 CPU 코어 수를 고려해서 적절하게 병렬로 처리한다 


    스트림의 생성과 연결

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.BinaryOperator;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
     
            Stream.of(11,22,33,44)
                    .forEach(n -> System.out.print(n + "\t"));
            System.out.println();
            
            
            Stream.of("So simple")
            .forEach(n -> System.out.print(n + "\t"));
            System.out.println();
            
            
            
            
            List<String> ls = Arrays.asList("Box" , "Simple","Complex","Robot");
            Stream.of(ls)
                    .forEach(w -> System.out.print(w + "\t"));
            System.out.println();
            
        }
    }
     
    cs

    위 스트림은 각자가 아니고 하나의 스태틱 스트림이다 . 


    DoubleStream , IntStream , LongStream 

    인터페이스 Stream <T>에 기본형이 없으므로 위와 같은 인터페이스가 정의되어있음 


    FlatMapStream 

    flatMap에 전달할 람다식에서는 스트림을 생성하고 이를 반환해야한다. 

    반면 map에 전달할 람다식에서 스트림을 구성할 데이터만 반환하면 된다. 


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.BinaryOperator;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            
            Stream<String> ss1 = Stream.of("My_Age","your_Life");
            
            //아래 람다식에서 스트림을 생성
            Stream<String> ss2 = ss1.flatMap(s -> Arrays.stream(s.split("_")));
            ss2.forEach(s->System.out.print(s + "\t"));
            System.out.println();
        }
    }
     
    cs


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.BinaryOperator;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            
            Stream<String> ss1 = Stream.of("My_Age","your_Life");
            
            //아래 람다식에서 스트림을 생성
            ss1.flatMap(s -> Arrays.stream(s.split("_")))
                .forEach(s->System.out.print(s + "\t"));
            System.out.println();
        }
    }
     
    cs

    Map은 그냥 결과 값만 바꾼다면 flapMap은 스트림형태로 변환한다.


    정렬

    정렬기능을 제공하는 중간 연산 메소드 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.BinaryOperator;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            
            Stream.of("box","apple","robot")
                    .sorted()
                    .forEach(s-> System.out.print(s + '\t'));
            System.out.println();
            
            Stream.of("Box","apple","Rabbit")
                    .sorted((s1,s2)-> s1.length() - s2.length())
                    .forEach(s-> System.out.print(s + '\t'));
            System.out.println();
            
        }
    }
     
    cs

    comparatorble<T> 인테페이스를 구현하고 있어야한다. 


    루핑 


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package com.java.www;
     
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.BinaryOperator;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
            
            //최종 연산이 생략 
            IntStream.of(1,3,5)
                    .peek( d-> System.out.print(d + "\t"));
            System.out.println();
            
            //최종연산이 존재
            IntStream.of(5,3,1)
            .peek( d-> System.out.print(d + "\t"))
            .sum();
            System.out.println();    
        }
    }
     
    cs


    5 3 1


    최종연산이 존재하지 않는 중간연산은 연산되지 않음


    최종연산자

    sum() : 합

    count() : 개수

    average() : 평균

    min() : 최소

    max() : 최대 


    allMatch() :  스트림안의 데이터가  모두 조건에 성립하는가?

    anyMatch() : 하나라도 성립하는가?

    noneMatch() : 모두 false인가?

    반환값 boolean



    collect

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package com.java.www;
     
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.BinaryOperator;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
     
            String[] word = {"Hello" ,"Box" ,"Robot","Toy"};
            Stream<String> ss = Arrays.stream(word);
            
            List<String> ls = ss.filter(s->s.length() < 5)
                                .collect(()-> new ArrayList<>(), 
                                        (c,s) -> c.add(s),
                                        (lst1,lst2)-> lst1.addAll(lst2));
            System.out.println(ls);
            
        }
    }
     
    cs


    중간연산에서 길이가 5미만인 문자열만 거름 

    그리고 최종연산


        .collect(()-> new ArrayList<>(), 

                                        (c,s) -> c.add(s),

                                        (lst1,lst2)-> lst1.addAll(lst2));

    위 문장에서 첫번째 매개변수로 전달된 람다식은 다음과 같다 .

    Collect 메소드는 이 람다식 기반으로 데이터를 저장할 저장소를 생성

    () -> new ArrayList<>()

    두번째 매개변수로 전달된 다음람다식을 관찰하자 

    (c,s) -> c.add(s)

    위 람다식에서는 c는 collect의 첫번째 인자를 통해서 생성된 컬렉션인스턴스이고 

     s는 스트림을 이루는 데이터들이다.

    이 문장을 통해서 컬렉션인스턴스에 스트림이 저장된다.

    그리고 데이터 저장이 끝나면 이 컬렉ㄱ션 인스턴스의 참조값이 반환되면서 

    collect 연산이 마무리됨 

     (lst1,lst2)-> lst1.addAll(lst2)

    3번째 인자로 전달된 람다식은 무슨의미가있을까 

    위 예제와 같은 순차스트림인경우 세변째 인자는 사용되지 않음

    그렇다고 null을 전달하면 nullpointException이 발생하니 

    병렬스트림을 고려한 람다식을 작성해야한다.


    병렬 스트림에 collect


    앞서 예제에서 보인 collect 메소드의 호출문은 다음과 같음


      .collect(()-> new ArrayList<>(), 

                                        (c,s) -> c.add(s),

                                        (lst1,lst2)-> lst1.addAll(lst2));

    병렬처리를 하면 각자의 데이터의 저장이 끝난후에

    다시 하나로 합치는 과정을 거쳐야하는 데 

    그 방법이 3번째 인자의 람다식이다.

    addAll 메소드는 첫번째 람다식에서 생성한 컬렉션 인스턴스의 메소드로써 

    메소드의 호출 결과로 lst2가 저장하고 있는 모든 데이터가 lst1담기게됨


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    package com.java.www;
     
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.BinaryOperator;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
     
    public class MyFirstStream2 {
        public static void main(String[] args) {
     
            String[] word = {"Hello" ,"Box" ,"Robot","Toy"};
            Stream<String> ss = Arrays.stream(word);
            
            List<String> ls = ss.parallel()
                                .filter(s->s.length() < 5)
                                .collect(()-> new ArrayList<>(), 
                                        (c,s) -> c.add(s),
                                        (lst1,lst2)-> lst1.addAll(lst2));
            System.out.println(ls);
            
        }
    }
     
    cs

    병렬 스트림 얘제


    'java' 카테고리의 다른 글

    스트림  (0) 2019.05.21
    자바로 배우는 리팩토리 입문 0장  (0) 2019.05.12
    OS 메모리사용량, CPU사용량  (0) 2019.05.08
    HTTPS 통신  (0) 2019.05.02
Designed by Tistory.