쵼쥬
쵼쥬의 개발공부 TIL
쵼쥬
전체 방문자
오늘
어제
  • 분류 전체보기 (276)
    • 코딩테스트 (192)
      • [알고리즘] 알고리즘 정리 (7)
      • [백준] 코딩테스트 연습 (126)
      • [프로그래머스] 코딩테스트 연습 (59)
    • Spring (71)
      • [인프런] 스프링 핵심 원리- 기본편 (9)
      • [인프런] 스프링 MVC 1 (6)
      • [인프런] 스프링 MVC 2 (4)
      • [인프런] 실전! 스프링 부트와 JPA 활용1 (7)
      • [인프런] 실전! 스프링 부트와 JPA 활용2 (5)
      • [인프런] 실전! 스프링 데이터 JPA (7)
      • [인프런] 실전! Querydsl (7)
      • JWT (5)
      • [인프런] Spring Cloud (17)
      • [인프런] Spring Batch (4)
    • Java (6)
      • [Java8] 모던인자바액션 (4)
      • [부스트코스] 웹 백엔드 (2)
      • [패스트캠퍼스] JAVA STREAM (0)
    • CS (6)
      • 디자인 패턴과 프로그래밍 패터다임 (2)
      • 네트워크 (4)

블로그 메뉴

  • 홈

공지사항

인기 글

태그

  • 누적합
  • spring
  • 코딩테스트
  • 타임리프
  • 프로그래머스
  • 백준
  • 자바
  • 비트마스킹
  • Spring Data JPA
  • 구현
  • MVC
  • 인프런
  • querydsl
  • 위클리 챌린지
  • 스프링
  • 백분
  • 부스트코스
  • 알고리즘
  • BFS
  • jpa

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
쵼쥬

쵼쥬의 개발공부 TIL

스트림 활용
Java/[Java8] 모던인자바액션

스트림 활용

2022. 2. 15. 15:46

필터링

filter 메서드

  • boolean을 반환하는 함수를 인수로 받아서 일치하는 모든 요소를 포함하는 스트림 반환

 

distinct 메서드

  • 고유 요소로 이루어진 스트림을 반환 (중복 제거) 

 

스트림 슬라이싱

자바 9 는 스트림의 요소를 효과적으로 선택할 수 있도록 takeWhile, dropWhile 새로운 메서드 지원

 

takeWhile

  • filter 와 달리 참이 아닐경우 거기서 멈춤 (filter는 참인 요소 모두 확인해서 가져옴)

 

dropWhile

  • 거짓이 되는 지점까지 발견된 요소를 버린다. (takeWhile과 반대)
List<Dish> sliceMenu1 =
        menu.stream()
                .filter(dish -> dish.getCalories() < 320)
                .collect(Collectors.toList());

List<Dish> sliceMenu2 =
        menu.stream()
                .takeWhile(dish -> dish.getCalories() < 320)
                .collect(Collectors.toList());

List<Dish> sliceMenu3 =
        menu.stream()
                .dropWhile(dish -> dish.getCalories() < 320)
                .collect(Collectors.toList());

 

limit

  • n 이하의 크기를 갖는 새로운 스트림 반환
List<Dish> sliceMenu =
        menu.stream()
                .filter(dish -> dish.getCalories() < 320)
                .limit(3)
                .collect(Collectors.toList());

 

skip

  • 처음 n개 요소를 제외한 스트림 반환
List<Dish> sliceMenu =
        menu.stream()
                .filter(dish -> dish.getCalories() < 320)
                .skip(2)
                .collect(Collectors.toList());

 

매핑

map

  • 인수로 제공된 함수는 각 요소에 적용되며 함수를 적용한 결과가 새로운 요소로 매핑된다.
List<String> dishNames =
        menu.stream()
                .map(Dish::getName)
                .collect(Collectors.toList());

 

flatMap

  • 생성된 스트림을 하나의 스트림으로 평면화
// map 으로 전달한 람다는 각 단어의 String[](문자열 배열)을 반환한다는 점이 문제이다.
// map 메서드가 반환한 스트림의 형식은 Stream<String[]> 이다.
words.stream()
        .map(word -> word.split(""))
        .distinct()
        .collect(Collectors.toList());

// Array.stream() 사용해서 해결하게 되면 별도의 스트림 리스트(List<Stream<String>>)이 만들어지면서 문제가 해결되지 않는다.
words.stream()
        .map(word -> word.split(""))
        .map(Arrays::stream)
        .distinct()
        .collect(Collectors.toList());

// flatMap 을 사용하면 해결가능
// flatMap은 각 배열을 스트림이 아니라 스트림의 콘텐츠로 매핑한다.
// 즉, 하나의 평면화된 스트림을 반환
words.stream()
        .map(word -> word.split(""))
        .map(Arrays::stream)
        .distinct()
        .collect(Collectors.toList());

 

검색과 매칭

anyMatch

  • 적어도 한 요소와 일치하는지 확인
// menu에 채식 요리가 있는지 확인
if (menu.stream().anyMatch(Dish::isVegetarian)) {
    System.out.println("The menu is (somewhat) vegetarian friendly");
}

 

allMatch

  • 모든 요소와 일치하는지 확인
// 모든 요리가 1000 칼로리 이하면 건강식으로 간주 
boolean isHealthy = menu.stream().allMatch(dish -> dish.getCalories() < 1000);

 

noneMatch

  • 일치하는 요소가 없는지 확인 (allMatch와 반대)
// 위와 동일
boolean isHealthy = menu.stream().allMatch(dish -> dish.getCalories() >= 1000);

 

findAny

  • 현재 스트림에서 임의의 요소 반환
// 임의의 채식 요리 선택
Optional<Dish> dish = menu.stream()
        .filter(Dish::isVegetarian)
        .findAny();

 

Optional<T> 클래스는 값의 존재나 부재 여부를 표현하는 컨테이너 클래스 

null은 쉽게 에러를 일으킬 수 있으므로 자바 8에서 Optional<T>를 만들었다.

  • isPresent() : Optional이 값을 포함하면 참, 포함하지 않으면 거짓 반환
  • ifPresent(Consumer<T> block) : 값이 있으면 주어진 블록 실행
  • T get() : 값이 존재하면 값을 반환, 값이 없으면 NoSuchElementException 일으킴
  • T orElse() : 값이 있으면 값 반환, 없으면 기본값 반환

 

findFrist

  • 첫번째 요소 반환

 

리듀싱

  • 모든 스트림 요소를 처리해서 값으로 도출하는 연산
  • '메뉴의 모든 칼로리의 합계를 구하시오.' '메뉴에서 칼로리가 가장 높은 요리는?' 와 같이 스트림 요소를 조합해서 더 복잡한 질의를 표현하는 연산

 

reduce

int sum = 0;
for (int x : numbers) {
    sum += x;
}

int sum = numbers.stream().reduce(0, (a, b) -> a + b);

int product = numbers.stream().reduce(1, (a, b) -> a * b);

 

초깃값 없는 reduce

  • Optional 객체 반환
Optional<Integer> product = numbers.stream().reduce((a, b) -> a * b);

 

  • 최댓값, 최솟값 찾을수 있다.
Optional<Integer> max = numbers.stream().reduce(Integer::max);

 

count

  • 스트림 요소 수를 세는 메서드

 

숫자형 스트림

기본형 특화 스트림

  • IntStream
  • DoubleStream
  • LongStream

 

스트림을 기본형 특화 스트림으로 변환할 때 

  • mapToInt
  • mapToDouble
  • mapToLong
// 각 요리에서 칼로리 추출해서 더함
int calories= menu.stream()
        .mapToInt(Dish::getCalories)
        .sum();

 

기본형 특화 스트림을 스트림으로 변환

  • mapToObj

 

예) 피타고라스를 만족하는 세 수

Stream<int[]> pythagoreanTriples =
        IntStream.rangeClosed(1, 100).boxed()
                .flatMap(a -> IntStream.rangeClosed(a, 100)
                        .filter(b -> Math.sqrt(a * a + b * b) % 1 == 0)
                        .mapToObj(b -> new int[]{a, b, (int) Math.sqrt(a * a + b * b)})
                );

rangeClosed : 주어진 범위의 수를 만듬

boxed : Intstream을 Stream<Integer>로 복원

flatMap : 생성된 각각의 스트림을 하나의 평준화된 스트림으로 만듬

 

pythagoreanTriples
        .limit(5)
        .forEach(t -> System.out.println(t[0] + " " + t[1] + "  " + t[2]));

실행 결과

개선

기존에는 만족하는 수를 찾아서 넣어줬지만 개선한 코드는 a,b,c 세 수를 만든 다음에 우리가 원하는 조건으로 필터링

Stream<double[]> pythagoreanTriples2 =
        IntStream.rangeClosed(1, 100).boxed()
                .flatMap(a -> IntStream.rangeClosed(a, 100)
                        .mapToObj(b -> new double[]{a, b, Math.sqrt(a * a + b * b)})
                        .filter(t -> t[2] % 1 == 1)
                );

 

스트림 생성

Stream.of

  • 값으로 스트림을 만듬
Stream<String> stream = Stream.of("Modern ", "Java ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);

 

Stream.ofNullable

  • null이 될 수 있는 객체를 스트림으로 만들 수 있다.
Stream<String> homeValueStream = Stream.ofNullable(System.getProperty("home"));
// System.getProperty 제공된 키에 대응하는 속성이 없으면 Null 반환 (home 에 대응하는 속성이 없어서 null)

Stream<String> values = Stream.of("config", "home", "user")
        .flatMap(key -> Stream.ofNullable(System.getProperty(key)));

 

Arrays.stream

  • 배열을 스트림으로 만듬
int[] numbers = {1,2,3,4,5};
int sum = Arrays.stream(numbers).sum(); // int 배열을 IntStream으로 변환

 

Stream.iterate, Stream.generate

  • 함수에서 스트림을 만들 수 있는 정적 메서드
  • 두 연산을 이용해서 무한 스트림, 즉 고정된 컬렉션에서 고정된 크기로 스트림을 만들었던 것과는 달리 크기가 고정되지 않은 스트림을 만들 수 있다.

 

iterate

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

 

generate

  • iterate와 달리 연속적으로 계산하지 않고 Supplier<T>를 인수로 받아서 새로운 값을 생산한다.
Stream.generate(Math::random)
        .limit(5)
        .forEach(System.out::println);

 

 

 

'Java > [Java8] 모던인자바액션' 카테고리의 다른 글

스트림  (0) 2022.02.15
람다 표현식  (0) 2022.02.11
동작 파라미터화 코드 전달  (0) 2022.02.09
    'Java/[Java8] 모던인자바액션' 카테고리의 다른 글
    • 스트림
    • 람다 표현식
    • 동작 파라미터화 코드 전달
    쵼쥬
    쵼쥬

    티스토리툴바