Проверьте наличие ключа HashMap

на Java, имея хеш-карту, полностью заполненную данными такой формы:

HashMap<Integer, int[]> map = new HashMap<Integer, int[]>(1000000, 1);

что быстрее при проверке существования случайного ключа, скажем 100:

if (map.get(100) == null))

или

if (!map.containsKey(100))

?

вопрос интересен с точки зрения микро-оптимизации.

4 ответов


на containsKey должно быть очень немного медленнее, потому что это приводит к дополнительному вызову функции (он просто вызывает getEntry) (он может быть оптимизирован, я не уверен, что Java сделает это). containsKey выглядит так:

public boolean containsKey(Object key) {
  return getEntry(key) != null;
}

но обратите внимание, что containsKey может быть, с другой стороны, очень немного быстрее другие Map реализации (но, вероятно, не те, что в стандартном API Java).

Обычно мои реализации выглядят так: (избегая необходимости containsKey)

int[] arr = map.get(100);
if (arr == null) // doesn't exist
  // do stuff
else // exists
  // do stuff with arr

ниже будет наверняка быть медленнее, чем выше: (если элементы, которые вы ищите существует достаточное количество времени)

if (!map.containsKey(100)) // doesn't exist
  // do stuff
else // exists
{
  int[] arr = map.get(100);
  // do stuff with arr
}

Edit: спасибо zvzdhk за предоставление источника containsKey. Вообще-то, я должен был проверить.


на самом деле оба подхода одинаковы. Если вы посмотрите в java.util.HashMap исходный код вы можете найти следующий containsKey реализации:

public boolean containsKey(Object key) {
    return getEntry(key) != null;
}

два отличается только в return тип за исключением того, что map.get(key) может вернуть вам null в случае, если его ключ, однако map.containsKey(key) вернуться boolean который может быть использован для distingush двух возможных случаев map.get(key) возвращение null.


нет никакой разницы между этими двумя подходами. Основная разница только в том, что вы собираетесь делать дальше. Если вам нужно значение, то, конечно, вам будет иметь значение.