프로그래머스 120812 - 최빈값 구하기

연어는결국강으로·2023년 2월 19일
0

알고리즘 공부

목록 보기
15/15

오늘 스터디 과제에서 프로그래머스 - 최빈값 구하기를 풀되 stream을 이용해서 풀으라고 했다.

어.... stream은 별로 익숙하지 않은데 요즘 계속 과제의 조건이 stream을 이용하는 것이어서 stream에 대해 좀 더 구체적으로 알게 되었다. 그리고 var의 경우에는 패스트캠퍼스의 대용량트래픽처리 강의 중 mysql 강의를 듣는데 var를 사용하는 것을 봤는데 이번에 intellij를 사용하면서 강제적으로 사용하게 되었다. 아래는 기록이다.

일단 최종적인 코드이다.

public int solution(int[] array) {
            Map<Integer, Integer> map = new HashMap<>();
            var ref = new Object() {
                Integer answer = 0;
                Integer value = 0;
                Integer count = 0;
            };

            System.out.println(ref.getClass().getName());

            Arrays.stream(array).forEach(i -> map.put(i, map.getOrDefault(i, 0) + 1));

            map.forEach((k, v) -> {
                if (Objects.equals(v, ref.value)) {
                    ref.count++;
                }
                if (v > ref.value) {
                    ref.answer = k;
                    ref.value = v;
                    ref.count = 0;
                }
            });

            if (ref.count != 0) {
                return -1;
            }

            return ref.answer;
        }

어... 일단 내가 새롭게 안 사실은 stream은 foreach나 다른 반복문처럼 직접적으로 raw하게 데이터를 가져다가 보는 것이 아니라 마치 proxy패턴처럼 값을 새로운 스레드에 복사해서 쓴다는 것이었다.

그러다 보니 이 stream으로 가져온 값을 수정할 수가 없었다. 예를 들자면, forEach(i -> i = 3) 이런식으로 수정하면 바로 컴파일에러를 뱉는다. 그럼 어쩌라는거야... 스트림으로 하라는데 값은 수정안되고;; 아주 명석한 intelliJ가 나에게 해답을 주었다.

바로 var를 이용해 익명 클래스를 이용하면, 원래는 익명 클래스를 만드는 경우 필드를 추가할 수 있지만, 다른 곳에서 해당 필드를 참조할 수 없으므로 에러를 발생시킨다.

하지만, var를 이용하면 익명 클래스에 선언된 필드를 사용할 수 있으므로 에러가 나지 않는다.

정리하면
1. stream으로 가져온 값은 수정할 수가 없다. 왜냐하면 이것은 stack자체를 새로 만들어서 쓰기 때문에 원래 있던 값들을 가져오고 이것들은 불변이어야 하기 때문이다.
2. var를 이용해서 익명클래스에 선언된 필드를 사용할 수 있다.

참고 링크
stream 쪽 다시 정리하기

Java 10 에서 var 재대로 사용하기 - 나중에 또 읽어보기
[Java 10] 자바 var

0개의 댓글