문자열에서 문자 개수를 세는 문제다.
책에서는 나에게 조금 덜 익숙한 HashMap을 사용해서 풀었는데 이 부분에 대해서 설명하려고 한다.
책 코드
public static Map<Character, Integer> countDuplicateCharacterV1(String str){
if(str == null || str.isBlank()){
return Collections.emptyMap();
}
Map<Character, Integer> map = new HashMap<>();
for(int i=0; i<str.length(); i++){
char ch = str.charAt(i);
map.compute(
ch, ((key, value) -> (value == null) ? 1 : ++value)
);
}
return map;
}
String 클래스의 isEmpty() 메서드의 기능은 알고 있었지만 isBlank()는 잘 몰랐다.
차이점을 간략하게 정리하자면
- isEmpty() : 문자열의 길이가 0인 경우에, true 리턴
- isBlank() : 문자열이 비어있거나, 빈 공백으로만 이루어져 있으면, true 리턴
[Java] isEmpty()와 isBlank()의 차이 - 어제 오늘 내일
문제는 compute() 메서드인데
키 값과 익명객체(람다식)를 넘겨받는 형식으로 구성되어 있는 것을 알 수 있었다.
remappingFunction.apply(key, oldValue);
이 코드는
BiFunction<Character, Integer, Integer> remappingFunction = new BiFunction<>() {
@Override
public Integer apply(Character key, Integer value) {
return (value == null) ? 1 : ++value;
}
};
요렇게 변환되어서 실행된다.(BiFunction의 구현되어야 하는 메서드가 하나이니 람다식을 넘기면 자동으로 apply() 메서드 구현)
우린 애초에 삼항연산자로 null 값을 넘기지 않으니 if(newValue == null)를 볼 필요는 없고 아래의 else 문에서 put(key, newValue) 메서드를 볼 수 있다.
결론적으로 compute() 메서드는 키와 람다식을 받아 람다식의 리턴값이 null 값이면 기존 키를 삭제, 아니면 값 추가하는 것으로 볼 수 있다. (값이 null 값이면 해시맵의 키 값을 유지할 필요가 없기 때문에 키 삭제)
잘 되는 것을 확인할 수 있다.
내가 바꾼 코드
public static Map<Character, Integer> countDuplicateCharacterVO(String str){
if(str == null || str.isBlank()){
return Collections.emptyMap();
}
Map<Character, Integer> map = new HashMap<>();
for(int i=0; i<str.length(); i++){
char ch = str.charAt(i);
if(map.containsKey(ch)){
map.put(ch, map.get(ch) + 1);
}else{
map.put(ch, 1);
}
}
return map;
}
내가 조금 더 보기 쉽게(?) 바꾼 코드이다.
기존에 키를 포함하고 있다면 기존 value 값에 +1을 해준다.
그리고 갑자기 든 생각인데 람다 관련해서 재밌는 유튜브 영상이 있다.
심심한 분들만 보는 거 추천...ㅎㅎ
(한 문제 풀기 쉽지 않네...)