map 안의 값을 변경하거나 새로 만들기 전에, 데이터가 이미 있는지 확인하기 위하여, java.util.Map.get()
결과를 null이랑 비교하거나, java.util.Map.containsKey()
를 사용하는 경우를 흔히 볼 수 있습니다.
하지만 java.util.Map
에는 computeIfPresent()
와 computeIfAbsent()
이라는 훌륭한 대안 메소드가 API 로 존재합니다.
가독성 좋은 코드와 깨끗한 코드가 되기 위해 이 인터페이스들을 대신 사용해주세요.
참고: 이 규칙은 프로젝트의 sonar.java.source의 값이 8보다 낮은 경우(java8) 검사하지 않습니다.
규칙을 어긴 코드
V value = map.get(key);
if (value == null) { // 규칙을 어긴 코드
value = V.createFor(key);
if (value != null) {
map.put(key, value);
}
}
if (!map.containsKey(key)) { // 규칙을 어긴 코드
value = V.createFor(key);
if (value != null) {
map.put(key, value);
}
}
return value;
규칙을 준수한 해결책
return map.computeIfAbsent(key, k -> V.createFor(k));
예외
이 규칙은 map에 null을 추가하려 할 때는 문제 상황이라고 알려주지 않습니다.
왜냐하면 computeIfAbsent
의 반환 값이 null 일 때는, 실제로 엔트리에 값을 넣지 않기 때문입니다. (^역: 아래 코드 참조)
Map<String, String> temp = new HashMap<>();
temp.put("foo", "bar");
temp.put("hello", null);
// case 1
temp.computeIfAbsent("foo", value -> {
System.out.println("이 코드는 실행되지 않습니다.");
return value;
});
// case 2
temp.computeIfAbsent("hello", value -> {
System.out.println("이 코드는 실행됩니다."); // 출력 결과: 이 코드는 실행됩니다.
return "world";
});
System.out.println(temp.containsKey("hello")); // 출력 결과: true
System.out.println(temp.get("hello")); // 출력 결과: world
// case 3
temp.computeIfAbsent("kok202", value -> {
System.out.println("이 코드는 실행됩니다."); // 출력 결과: 이 코드는 실행됩니다.
return null;
});
System.out.println(temp.containsKey("kok202")); // 출력 결과: false
같이보면 좋은 자료
-
S6104 Map에서
computeIfAbsent()
이나computeIfPresent()
을 null을 추가하기 위해 사용해선 안됩니다.
If you like SONARKUBE, don’t forget to give me a star.