Java의 HashMap에 널 키 또는 값을 추가하는 용도는 무엇입니까?


91

HashMap은 하나의 널 키와 임의의 수의 널 값을 허용합니다. 그것의 용도는 무엇입니까?


11
"아마도 문제는 아무것도 우리를 괴롭히지 않는 것이 아니라 우리가 괴롭히는 것입니다."
bmargulies

3
Guava, google collections에서 많은 클래스가 null을 허용하지 않으며 그 이유는 케이스의 95 %가 null이 필요하지 않으며 잠재적으로 찾기 어려운 버그를 나타낼 수 있다는 것입니다.
stivlo

이상한 점은 ConcurrentHashMapnull 키를 지원하지 않지만 지원 한다는 것입니다 HashMap.
codepleb

2
HashMap 만 null 허용 :)
subhashis

답변:


126

나는 당신이 무엇을 요구하고 있는지 확실하지 않지만, 만약 당신이 null 키를 사용하기를 원할 때의 예를 찾고 있다면, 나는 그것들을지도에서 자주 사용하여 기본 케이스 (즉, 사용해야하는 값)를 나타냅니다. 주어진 키가없는 경우) :

Map<A, B> foo;
A search;
B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);

HashMapnull 키를 특별히 처리 .hashCode()하지만 (null 개체를 호출 할 수 없기 때문에 ) null 값은 특별한 것이 아니므로 다른 것과 마찬가지로지도에 저장됩니다.


4
따라서 .hashCode ()가 null에서 가능하지 않은 경우 누가 null 키가 들어갈 캐리지를 결정합니까?
Pacerier

26
@Pacerier HashMap( putForNullKey)에는이를 처리 하는 특별한 방법 이 있습니다. 테이블 0에 저장
Michael Mrozek 2012

1
@MichaelMrozek 당신의 마지막 줄 B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);나는 우리가 단순히 동일한 결과를 가질 검색 키에서 get 메소드를 호출 할 수 있다고 생각합니다. B val = foo.get(search);내가 뭔가 잘못되면 나를 바로 잡을 수 있습니까?
dheerajraaj

6
@ dheeraj92 키가 존재하지 않으면 코드가로 설정 val됩니다 null. 광산은 null지도 에서 어떤 지도 로든 설정합니다 . 포인트는 것을, 나는에서 기본 null 이외의 값을 저장 null맵의 키와 실제 키가 존재하지 않는 경우에 사용
마이클 Mrozek

28

한 가지 예는 나무를 모델링하는 것입니다. HashMap을 사용하여 키가 부모이고 값이 자식 목록 인 트리 구조를 나타내는 경우 키 값은 null루트 노드가됩니다.


6

에 대한 사용의 일례 null 사용 a 언제 HashMap복귀있다 (예컨대, 외부 웹 서비스를 호출하는 등의) 고가의 작업의 결과를 캐시로 null.

퍼팅 null맵에 값하는 것은 다음 작업이 주어진 키 (수행되지 않은 경우를 구별 할 수 있습니다 cache.containsKey(someKey)반환 false), 작업을 수행하지만 반환 된 경우 null값 ( cache.containsKey(someKey)반환 true, cache.get(someKey)반환 null).

null값이 없으면 캐시에 특별한 값을 넣어 null응답 을 나타내 거나 해당 응답을 전혀 캐시하지 않고 매번 작업을 수행해야합니다.


3

지금까지의 대답은 null열쇠 가 있다는 것의 가치만을 고려 했지만 질문은에 대해 묻습니다 any number of null values.

nullHashMap에 키에 대한 값을 저장하는 이점은 데이터베이스 등에서와 동일합니다. 값이 비어있는 것과 (예 : 문자열 "") 값이 전혀없는 것 (null) 사이의 차이를 기록 할 수 있습니다. .


2

다음은 null키가 유용 할 수 있는 경우에 대한 내 유일하게 해석 된 예입니다 .

public class Timer {
    private static final Logger LOG = Logger.getLogger(Timer.class);
    private static final Map<String, Long> START_TIMES = new HashMap<String, Long>();

    public static synchronized void start() {
        long now = System.currentTimeMillis();
        if (START_TIMES.containsKey(null)) {
            LOG.warn("Anonymous timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(null).longValue()) +"ms"); 
        }
        START_TIMES.put(null, now);
    }

    public static synchronized long stop() {
        if (! START_TIMES.containsKey(null)) {
            return 0;
        }

        return printTimer("Anonymous", START_TIMES.remove(null), System.currentTimeMillis());
    }

    public static synchronized void start(String name) {
        long now = System.currentTimeMillis();
        if (START_TIMES.containsKey(name)) {
            LOG.warn(name + " timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(name).longValue()) +"ms"); 
        }
        START_TIMES.put(name, now);
    }

    public static synchronized long stop(String name) {
        if (! START_TIMES.containsKey(name)) {
            return 0;
        }

        return printTimer(name, START_TIMES.remove(name), System.currentTimeMillis());
    }

    private static long printTimer(String name, long start, long end) {
        LOG.info(name + " timer ran for " + (end - start) + "ms");
        return end - start;
    }
}

존재하지 않는 타이머 또는 이미 중지 된 타이머를 중지하려는 경우 무시되지 않고 오류 여야합니다.
기금 모니카의 소송

@QPaysTaxes-의도에 따라 다릅니다. 쉽게 사용할 수있는 가벼운 유틸리티를 원한다면 일반적으로 주변에 있는 것을 원하지 않습니다throw Exception . 게다가 존재하지 않거나 이미 중지 된 타이머를 중지하려는 시도가 호출자가 일반적으로 복구 할 수있는 것과는 다릅니다.
aroth

1

또 다른 예 : 날짜별로 데이터를 그룹화하는 데 사용합니다. 그러나 일부 데이터에는 날짜가 없습니다. "NoDate"헤더로 그룹화 할 수 있습니다.


0

널 키는 맵 키가 빈 필드를 나타내는 UI 선택에 대한 데이터를 맵에 저장할 때도 유용 할 수 있습니다.

해당하는 null 필드 값은 예를 들어 UI 선택에서 "(선택해주세요)"로 표시됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.