2013-12-16 3 views
0

Просматривая код put() из HashMap, я натолкнулся на странный фрагмент кода. Рассмотрим следующий фрагмент кода:Почему ключи сопоставлены в HashMap.put()?

490 public V put(K key, V value) { 
491  if (table == EMPTY_TABLE) { 
492   inflateTable(threshold); 
493  } 
494 if (key == null) 
495 return putForNullKey(value); 
496  int hash = hash(key); 
497  int i = indexFor(hash, table.length); 
498  for (Entry<K,V> e = table[i]; e != null; e = e.next) { 
499   Object k; 
500   if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 
501    V oldValue = e.value; 
502    e.value = value; 
503    e.recordAccess(this); 
504    return oldValue; 
505   } 
506  } 

В строке 500, почему ключ присваивается новой переменной k и затем используется в OR состоянии? Почему не может это быть записаны непосредственно следующим образом:

if (e.hash == hash && (e.key == key || key.equals(e.key))) { 


Я не знаю, почему написано именно так, но я уверен, что есть какая-то причина, почему за это кодируется так. Это какая-то оптимизация?
Может кто-то пролить свет на это?

ответ

1

Они сохраняют разницу в объекте.

(e.key == key || key.equals(e.key)) 

Это должно повторяться дважды в два раза.

Это следует один раз:

((k = e.key) == key || key.equals(k)) 

Экономия крошечная, хотя, и в современных компиляторов/оптимизаторы/и т.д. не может быть даже не экономить на всех. Помните, что этот код был написан много лет назад, и, скорее всего, кто-то пришел из фона программирования на C++, где такая вещь была более общей и полезной.

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

Смежные вопросы