Weil es [etwas mehr] mehr Arbeit leistet, siehe die OpenJDK 7-Quelle .
Beachten Sie, dass containsKey
getEntry
aufruft, während get
direkt "magic lookup" durchführt. Ich weiß nicht, warum es auf diese Weise gemacht wurde, und bin noch mehr verwirrt über die Verwendung / Nichtnutzung von getForNullKey
: Siehe John Bs und Ted Hopps Kommentare, warum das so ist.
get
hat eine frühe Codeaufteilung für einen Nullschlüssel (beachten Sie, dass get
null
zurückgibt, wenn der Eintrag nicht existiert oder mit einem gespeicherten Nullwert existiert):
Während getEntry
, aufgerufen von containsKey
, nicht in getForNullKey
aufgeteilt wird, gibt es hier zusätzliche Arbeit, um nach dem Nullschlüssel-Fall zu suchen (für jeden in der Kette gescannten Eintrag):
Außerdem hat containsKey
den zusätzlichen Bedingungs- und Methodenaufruf (beachten Sie, dass getEntry
ein Entry-Objekt zurückgibt, wenn der Schlüssel existiert, auch wenn der gespeicherte Wert null
ist):
Ich vermute, es könnte argumentiert werden, dass containsKey
- in Bezug auf "Leistung" - von einem spezialisierten Formular profitieren würde (auf Kosten von weniger DRY-Code), oder dass getEntry
dem Vorsprung von% folgen könnte co_de% mit einem frühen Null-Schlüssel-Check .. andererseits könnte man argumentieren, dass get
in get
geschrieben werden sollte; -)
Glückliche Kodierung.
Ich habe noch nicht versucht, Ihre Ergebnisse zu reproduzieren, aber meine erste Vermutung ist, dass get
einfach den Wert (falls vorhanden) zurückgibt, der gefunden wurde, während containsKey
(was Sie getestet haben, nicht contains
) muss getestet werden, ob der Schlüssel existiert (entweder mit einem Null- oder Nicht-Null-Wert) und dann einen booleschen Wert zurückgibt. Nur ein wenig mehr Aufwand beteiligt.
Beim Testen verschiedener Größen von hashmaps ist, wenn es eine Verzerrung in der Leistung gibt, diese sehr klein.
Wird auf Java 7 Update 1 mit einem 4,6 GHz i7 2600K ausgeführt.
%Vor%druckt für halbe Millionen Tasten
%Vor%druckt für eine Million Tasten
%Vor%jedoch für zwei Millionen Schlüssel
%Vor%für fünf Millionen Schlüssel
%Vor%BTW: Die Zeitkomplexität für get () und containsKey ist O (1) (auf einer idealisierten Maschine), aber Sie können sehen, dass für eine echte Maschine die Kosten mit der Größe der Map steigen.