ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] java8 stream
    JAVA 2021. 12. 17. 00:54

    java8부터 지원이 된 stream은 람다함수형식으로 간결하고 직관적으로 요소들을 처리가 가능한 기능이다.

    이러한 stream을 이용해 for문 등 직관적이지 않은 처리들을 깔끔하게 처리할 수 있다.

     

    Stream의 구조

    stream의 구조는 크게 세가지로 볼 수 있다.

    1. stream의 생성

    2. 중개 연산

    3. 최종 연산

     

    세가지로 구성되있으며, 중개연산은 연산결과를 stream형태로 반환하기 때문에 연속적으로 사용할 수 있다.

    대략적인 구조는

    데이터소스객체집합.stream생성().중개연산().최종연산();

    이다.

     

    Stream 생성

    스트림 api는 다음과 같은 다양한 종류의 소스들에 사용할 수 있다.

     

    1. 컬렉션

    2. 배열

    3. 가변 매개변수

    4. 지정된 범위의 연속된 정수

    5. 특정 타입의 난수

    6. 람다 표현식

    7. 파일

    8. 빈 스트림

     

    중개 연산

    중개 연산은 stream을 받아 stream형식으로 리턴하기 때문에 중개 연산을 연속으로 사용할 수 있다.

    stream의 중개연산은 필터-맵(filter-map)기반의 api를 사용함으로서 지연(lazy) 연산을 통해 성능을 최적화할 수 있다.

    대표적인 중개 연산들은

    1. stream 필터링 : filter(), distinct()

    2. stream 변환 : map(), flatMap()

    3. stream 제한 : limit(), skip()

    4. stream 정렬 : sorted()

    5. stream 연산 결과 확인 : peek()

     

    예시

    ArrayList<Int> list = new ArrayList<>(Arrays.asList(1, 5, 3, 5, 4, 5));
    
    //distinct 중복 제거
    list.stream().distinct().forEach(System.out::print);
    // 1534
    
    //filter 해당하는것만 필터링
    list.stream().filter(n -> n % 2 != 0).forEach(e -> System.out.print(e + " "));
    // 1 5 3 5 5
    
    
    ArrayList<String> list = new ArrayList<>(Arrays.asList("Drogba", "Essien", "Terry", "Lampard"));
    
    //map 스트림의 요소들을 인수로 전달하여, 반환값들로 새로운 스트림을 변환
    list.stream().map(String::toUpperCase()).forEach(System.out::println);
    // DROGBA ESSIEN TERRY LAMPARD
    
    ArrayList<String> list = new ArrayList<>(Arrays.asList(
        "I love Drogba", "I want to be Essien", "Terry is nice guy", "Lampard is best coach"));
    
    //flatmap 이차배열이나, 여럿문자열이 저장된 스트림을 단일스트림으로 변환
    list.stream().map(String::toUpperCase()).forEach(System.out::print);
    //IloveDrogbaIwanttobeEssienTerryisnoceguyLampardisbestcoach
    
    
    ArrayList<Int> list = new ArrayList<>(Arrays.asList(1, 5, 3, 5, 4, 5));
    
    //limit 앞요소 제거
    list.stream().skip(2).forEach(System.out::print);
    // 3545
    
    //filter 뒷요소 제거
    list.stream().limit(3).forEach(System.out::print);
    // 153

     

    최종 연산

    최종 연산은 앞서 중개 연산을 통해 만들어진 stream에 있는 요소들에 대해 마지막으로 각 요소를 소모하며 최종 결과를 보여준다. 즉 지연(lazy)되었던 모든 중개연산들이 최종 연산 시에 모두 수행된다. 이렇게 최종 연산시에는 모든 요소를 소모한 해당 stream은 더이상 사용할수없다.

    대표적인 최종연산 메소드들은 다음과 같다.

    1. 요소의 출력 : forEach()

    2. 요소의 소모 : reduce()

    3. 요소의 검색 : findFirst(), findAny()

    4. 요소의 검사 : anyMatch(), allMatch(), noneMatch()

    5. 요소의 통계 : count(), min(), max()

    6. 요소의 연산 : sum(), average()

    7. 요소의 수집 : collet()

     

    예시

     

    //findFirst(), findAny()  output 형식 Optional
    ArrayList<String> list = new ArrayList<>(Arrays.asList("넷", "둘", "하나", "셋"));
    
    Optional<String> first = list.stream().filter(s -> s.stratsWith("넷")).findFirst();
    //first.get() -> 넷
    
    Optional<String> any = list.stream().filter(s -> s.stratsWith("넷")).findAny();
    //any.get() -> 넷
    //findFirst, findAny 차이 -> findAny는 병렬처리 첫번째값 리턴으로 매 리턴마다 값이 다를 수 있다.
    
    
    //allMatch(), anyMatch(), noneMatch() output 형식 boolean
    ArrayList<Int> list = new ArrayList<>(Arrays.asList(3, 7, 5, 4, 4, 2, 9));
    
    
    boolean result = list.stream().allMatch(a -> a%2 == 0);
    //false 모든값이 해당하면 true
    
    boolean result = list.stream().anyMatch(a -> a%2 == 0);
    //true 해당값 하나라도 있으면 true
    
    boolean result = list.stream().noneMatch(a -> a%6 == 0);
    // true 모든값이 해당되지 않으면 true
    
    
    //collect()
    ArrayList<Int> list = new ArrayList<>(Arrays.asList(3, 7, 5, 4, 4, 2, 9));
    List<String> list = list.stream().filter(n -> n % 2 ! = 0).collect(Collectors.toList()); // 스트림을 리스트로 변환
    
    //Collectors 클래스의 partitioningBy()
    ArrayList<String> list = new ArrayList<>(Arrays.asList("넷", "둘", "하나", "셋"));
    //해당 stream의 각 요소별 글자 수에 따라 홀수와 짝수로 나누어 저장
    
    Map<Boolean, List<String>> partition = list.stream().collect(Collectors.partitioningBy(s -> (s.length() % 2) == 0));
    List<String> oddLengthList = patition.get(false);//넷, 둘, 셋
    List<String> evenLengthList = patition.get(true);//하나

     

     

     

    출처 : [Java] Java 8 Stream이란? (tistory.com)

    댓글

Designed by Tistory.