2015-07-01 1 views
2

У меня есть различные вопросы, касающиеся карт:Как работают Hashmaps, Treemaps и LinkedHashmaps на Java?

  1. Когда итерация в HashMap, не будет никакой гарантии о порядке итерации. Теперь почему?
  2. Почему хэш-карты быстрее, чем Treemaps?
  3. Как работают LinkedHashMaps, как они поддерживают заказ? Это потому, что у них есть дважды связанный список, содержащий информацию о том, какая запись хранится до и после записи?

Я читал документ API, но поскольку я начинаю заниматься программированием, у меня возникли проблемы с его пониманием.

+2

Вы должны уточнить, что вы не понимаете. Мы могли бы просто дать вам те же объяснения, которые вы уже не получили. – tnw

+0

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

+2

В качестве учебника вы можете прочитать [это] (https://en.wikipedia.org/wiki/Hash_table) и [это] (https://en.wikipedia.org/wiki/Red%E2%80%93black_tree) , так что вы поймете, как работают хэш-таблицы/карты и бинарные деревья (в частности, красно-черные деревья, используемые TreeMap). Что касается третьего вопроса, то ответ: да. :) – biziclop

ответ

5

Когда итерация в HashMap, не будет никакой гарантии о порядке итерации. Теперь почему?

Они вставлены не в порядке их возникновения, но какое значение они имеют.

Например, предположим, что у нас есть хеш-функция h (x), которая возвращает 127 для строки «Hello» и 12 для «Zebra». Если мы вводим эти ключи в нашу хэш-карту, порядок, в котором они считываются, - это «Zebra» -> (независимо от значения), затем «Hello» -> (любое значение прилагается).

Это проявляется в исходном коде для HashMap:

public V put(K key, V value) { 
    return putVal(hash(key), key, value, false, true); 
} 

Имейте в виду, что это упрощенная вариация на тему того, что на самом деле делает хэширования и представляет. Это может быть случай, когда есть столкновение по хеш-значению, и что столкновения нужно решать определенным образом. Это подразумевается как праймер; ключ вводится в порядке его хеша, но если ваша хеш-функция имеет недостатки или у вас нет хорошего значения для хэша вашего объекта, вы можете столкнуться с аберрантным поведением.

Почему Hashmaps быстрее Treemaps?

Операция хеша не зависит от размера общей коллекции. Напомним, что h (x) работает только на основе единственного значения, которое мы пытаемся вставить. Если мы вставляем элементы в TreeMap, мы должны рассмотреть, в каком естественном порядке они находятся, - и это включает в себя перемещение структуры, чтобы найти место для вставки, а также может включать в себя перебалансировку или реорганизацию структуры, чтобы гарантировать, что баланс сохранились.

Есть лот подробнее к источнику для метод.

public V put(K key, V value) { 
    Entry<K,V> t = root; 
    if (t == null) { 
     compare(key, key); // type (and possibly null) check 

     root = new Entry<>(key, value, null); 
     size = 1; 
     modCount++; 
     return null; 
    } 
    int cmp; 
    Entry<K,V> parent; 
    // split comparator and comparable paths 
    Comparator<? super K> cpr = comparator; 
    if (cpr != null) { 
     do { 
      parent = t; 
      cmp = cpr.compare(key, t.key); 
      if (cmp < 0) 
       t = t.left; 
      else if (cmp > 0) 
       t = t.right; 
      else 
       return t.setValue(value); 
     } while (t != null); 
    } 
    else { 
     if (key == null) 
      throw new NullPointerException(); 
     @SuppressWarnings("unchecked") 
      Comparable<? super K> k = (Comparable<? super K>) key; 
     do { 
      parent = t; 
      cmp = k.compareTo(t.key); 
      if (cmp < 0) 
       t = t.left; 
      else if (cmp > 0) 
       t = t.right; 
      else 
       return t.setValue(value); 
     } while (t != null); 
    } 
    Entry<K,V> e = new Entry<>(key, value, parent); 
    if (cmp < 0) 
     parent.left = e; 
    else 
     parent.right = e; 
    fixAfterInsertion(e); 
    size++; 
    modCount++; 
    return null; 
} 

Как работают LinkedHashMaps, как они поддерживают порядок? Это потому, что у них есть дважды связанный список, содержащий информацию о том, какая запись хранится до и после записи?

You can read the source for yourself, но основной вынос здесь:

  • Ключи все еще группируются в хэш-структуру, чтобы обеспечить их уникальность.
  • Порядок, в котором они вставлены, сохраняется структурой FIFO, как связанный список.

Думайте об этом так: вы используете хеш-функцию, чтобы убедиться, что ключ уникален, и если это так, вы тут же вставляете его и его значение в список. Таким образом, сохраняются как упорядоченность, так и уникальность.

+0

* Если мы введем эти значения в нашу хэш-карту *. Вы говорите о вводе значений хэша в значения «HashMap» или «String»? Также вы имеете в виду * keys * вместо * values ​​*? – CKing

+0

Позвольте мне прояснить это. Это должны быть ключи, а не значения. – Makoto

+0

Это прояснилось для меня, спасибо. – Gekal

-2

Короче говоря: Карты и наборы обычно представляют собой несортированные структуры данных. Если вы хотите «отсортированные наборы», вам, вероятно, лучше использовать списки или массивы.

Ваш вопрос скорее о структурах данных, а не о конкретной конкретной или связанной с Java проблеме программирования, следовательно, вы должны начать с чтения о thoses. (извините, чтобы получить возможность отправлять в ответ: комментирование вопросы необходимо 50 РЭП)

+1

Вы должны были сказать это в комментарии. Это недействительный ответ. Это предложение, и оно недостаточно детально. – Madhan

+0

Вы также объединяете сортировку и заказ. «HashMap» и «HashSet» являются * неупорядоченными * в целом, но это не означает, что вы не можете сортировать данные (или даже заказывать). – Makoto

+0

Неверно, например, TreeMap vs HashMap, TreeSet против HashSet. Кроме того, если вам нужен набор, зачем вам использовать списки или массивы? Членство в наборе - это O (1) или O (LogN) для классов Set. Использование списков и массивов в виде наборов - просто плохая идея. –

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