5.7.3 숫자 스트림 활용: 피타고라스

kkambbak1·2023년 4월 12일
0

https://github.com/BanditBool2/ReadingRecord/issues/23

p186~187 에서

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)})
                ).forEach(i-> System.out.println(Arrays.toString(i)));

map이 아닌 mapToObj를 쓰는 이유를 잘 모르겠습니다.


->MapToObj를 쓰는 이유

a와 b값 둘을 만들기 위해서 flatMap을 사용했다.

map은 map(Function<T, R>)
flatMap은 flatMap(Function<T, Stream<R>>)이다.

따라서, Stream으로 매핑을 해주어야한다.

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)})
                ).forEach(i-> System.out.println(Arrays.toString(i)));

-> 최적화

sqrt를 두번 사용하므로, 더 최적화를 하자면,

IntStream.rangeClosed(1, 100)
    .boxed()
    .flatMap(a -> IntStream.rangeClosed(a, 100)
        .mapToObj(b -> {
            int cSquared = a*a + b*b;
            int c = (int)Math.sqrt(cSquared);
            return c*c == cSquared ? new int[]{a, b, c} : null;
        })
        .filter(arr -> arr != null)
    )
    .forEach(arr -> System.out.println(Arrays.toString(arr)));

mapToObj 내에서 배열을 생성해줄 수 있다.


+mapToObj를 이용해서 boxed()와 map() 과정을 하나로 합쳐줄 수 있다.

IntStream.rangeClosed(1, 100) // IntStream
  .filter(b -> Math.sqrt(a*a + b*b) % 1 == 0) 
  .boxed() // Stream<Integer>로 boxing
  .map(b -> new int[]{a, b, (int) Math.sqrt(a*a + b*b)});

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

도움주신분 parkchaewon18, hanbonghun

profile
윤성

0개의 댓글