람다, Stream 사용한 주사위 연습문제

김도형·2023년 1월 1일
0

문제

예상 결과

두 주사위의 값들을 더했을 때 6이 나오는 값 2개를 배열로 출력

풀이

Stream<Integer> -> Stream<int []> 
  1. 2개의 주사위로 나올 수 있는 배열을 만들어야함.
  2. 위 코드 반환타입으로 나오기 위해서는 map 대신 flatmap 중간 연산을 사용해서 Stream 생성
  3. 생성된 Stream을 filter 사용해서 두 개의 값이 6 이 되는 것을 출력
public class DiceQuizMod {
    public static void main(String[] args) {
        Stream<Integer> dice = IntStream.rangeClosed(1, 6).boxed();
        dice.flatMap(i -> Stream.of(1, 2, 3, 4, 5, 6).map(i2 -> new int[] {i , i2}))
                .filter(iArr -> iArr[0]+iArr[1] == 6)
                .forEach(iArr -> System.out.println(Arrays.toString(iArr)));
    }
}

map 대신 flatmap을 사용한 이유

일단 flatmap 의 내부는 Integer -> Stream<int[]> 반환이 된다.

그런데 flatmap 대신 map을 사용한다면 어떻게 될까?
우리가 원하지 않는 스트림의 스트림이 나와 forEach 를 두번 사용해야 int[] 타입의 반환값이 출력이 된다.

우리는 스트림의 스트림 안에 int[] 필요하기 때문에 flatmap을 사용한다.

그림으로 표현하면,
{1,1}, {1,2}, {1,3}... 값이 필요하기 때문에 flatmap를 사용하여 가장 작은 단위의 단일 스트림만 출력하면 된다.

flatMap의 특징

  • Array나 Object로 감싸져 있는 모든 원소를 단일 원소 스트림으로 반환
  • map()은 입력한 원소를 그대로 스트림으로 반환하지만, flatMap()은 입력한 원소를 가장 작은 단위의 단일 스트림으로 반환한다.

간단히 flatMap 을 사용하면
입력한 원소를 가장 작은 단위의 단일 스트림으로 반환한다 것은,

// map 사용
Stream<Integer> -> Stream<Stream<int[]>> 
// 위 스트림에서 가장 작은 단위는 int[] 로 flatMap을 사용하며
Stream<Integer> -> Stream<int[]> 

출처 : 저자 남궁성, 자바의 정석 3판
http://www.yes24.com/Product/Goods/24259565

profile
3년간 웹/앱, 자동제어 QA 🔜 개발자로 전향하여 현재 교육 회사에서 백엔드 개발자로 근무 중입니다.(LinkedIn : https://www.linkedin.com/in/dohyoung-kim-5ab09214b)

0개의 댓글