Разница между HashMap, LinkedHashMap и TreeMap

678

В чем разница между HashMap, LinkedHashMap и TreeMap в Java? Я не вижу разницы в выходе, поскольку все три имеют keySet и values. Что такое Hashtable s?

Map m1 = new HashMap();
m1.put("map", "HashMap");
m1.put("schildt", "java2");
m1.put("mathew", "Hyden");
m1.put("schildt", "java2s");
print(m1.keySet()); 
print(m1.values()); 

SortedMap sm = new TreeMap();
sm.put("map", "TreeMap");
sm.put("schildt", "java2");
sm.put("mathew", "Hyden");
sm.put("schildt", "java2s");
print(sm.keySet()); 
print(sm.values());

LinkedHashMap lm = new LinkedHashMap();
lm.put("map", "LinkedHashMap");
lm.put("schildt", "java2");
lm.put("mathew", "Hyden");
lm.put("schildt", "java2s");
print(lm.keySet()); 
print(lm.values());
Теги:
map

13 ответов

907
Лучший ответ

Все три класса реализуют интерфейс Map и предлагают в основном те же функции. Наиболее важным отличием является порядок, в котором происходит итерация через записи:

  • HashMap не дает никаких гарантий относительно порядка итераций. Он может (и будет) даже полностью меняться при добавлении новых элементов.
  • TreeMap будет выполнять итерацию в соответствии с "естественным порядком" ключей в соответствии с их методом compareTo() (или внешним Comparator). Кроме того, он реализует интерфейс SortedMap, который содержит методы, которые зависят от этого порядка сортировки.
  • LinkedHashMap будет выполнять итерацию в том порядке, в котором записи были помещены в карту

"Hashtable" - это общее название для карт с хэш-настройками. В контексте Java API, Hashtable является устаревшим классом со дней Java 1.1 до того, как существовала структура коллекций. Его больше не следует использовать, поскольку его API загроможден устаревшими методами, которые дублируют функциональность, а его методы синхронизируются (что может снизить производительность и, как правило, бесполезно). Используйте ConcurrrentHashMap вместо Hashtable.

  • 1
    Что же такое Map на самом деле и в чем разница между Map, HashMap и Hashtables.
  • 4
    @theband: карта - это интерфейс. HashMap и Hashtable оба реализуют это; как я писал, Hashtable - это унаследованный класс.
Показать ещё 5 комментариев
1235

Я предпочитаю визуальное представление:

╔══════════════╦═════════════════════╦═══════════════════╦═════════════════════╗
║   Property   ║       HashMap       ║      TreeMap      ║     LinkedHashMap   ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║              ║  no guarantee order ║ sorted according  ║                     ║
║   Order      ║ will remain constant║ to the natural    ║    insertion-order  ║
║              ║      over time      ║    ordering       ║                     ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║  Get/put     ║                     ║                   ║                     ║
║   remove     ║         O(1)        ║      O(log(n))    ║         O(1)        ║
║ containsKey  ║                     ║                   ║                     ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║              ║                     ║   NavigableMap    ║                     ║
║  Interfaces  ║         Map         ║       Map         ║         Map         ║
║              ║                     ║    SortedMap      ║                     ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║              ║                     ║                   ║                     ║
║     Null     ║       allowed       ║    only values    ║       allowed       ║
║ values/keys  ║                     ║                   ║                     ║
╠══════════════╬═════════════════════╩═══════════════════╩═════════════════════╣
║              ║   Fail-fast behavior of an iterator cannot be guaranteed      ║
║   Fail-fast  ║ impossible to make any hard guarantees in the presence of     ║
║   behavior   ║           unsynchronized concurrent modification              ║
╠══════════════╬═════════════════════╦═══════════════════╦═════════════════════╣
║              ║                     ║                   ║                     ║
║Implementation║      buckets        ║   Red-Black Tree  ║    double-linked    ║
║              ║                     ║                   ║       buckets       ║
╠══════════════╬═════════════════════╩═══════════════════╩═════════════════════╣
║      Is      ║                                                               ║
║ synchronized ║              implementation is not synchronized               ║
╚══════════════╩═══════════════════════════════════════════════════════════════╝
  • 3
    Спасибо за наглядную презентацию. Можете ли вы предоставить некоторые ссылки для списка и установить визуальное представление. Еще раз спасибо.
  • 13
    В дополнение к порядку вставки LinkedHashMap также поддерживает порядок доступа (при использовании конструктора с логическим параметром порядка доступа).
Показать ещё 5 комментариев
53

Все три представляют собой сопоставление от уникальных ключей к значениям и, следовательно, реализуют интерфейс Map.

  • HashMap - это карта, основанная на хэшировании ключей. Он поддерживает операции O (1) get/put. Ключи должны иметь последовательные реализации hashCode() и equals(), чтобы это работало.

  • LinkedHashMap очень похож на HashMap, но он добавляет осознание в порядок, по которому элементы добавляются (или доступны), поэтому порядок итерации совпадает с порядком размещения (или порядком доступа, в зависимости от параметров конструкции).

  • TreeMap - это отображение на основе дерева. Его операции put/get принимают время O (log n). Для этого требуется, чтобы элементы имели некоторый механизм сравнения, либо со сравнением, либо с компаратором. Порядок итераций определяется этим механизмом.

  • 1
    Так что, если я правильно понимаю, единственное различие между LinkedHashMap и TreeMap заключается в производительности, учитывая, что порядок вставки такой же, как естественный порядок?
  • 19
    @MosheShaham Как он сказал в # 2: LinkedHashMap будет выполнять итерацию в порядке вставки, а не в естественном порядке. Так что, если вы добавите (2,5,3) в LinkedHashMap и сделаете для каждого над ним, он вернет 2,5,3 . Если это 2,5,3 для TreeMap он вернет 2,3,5 .
Показать ещё 4 комментария
35

Смотрите, где каждый класс находится в иерархии классов на следующей диаграмме (больше). TreeMap реализует SortedMap и NavigableMap, а HashMap - нет.

HashTable является устаревшим, и следует использовать соответствующий класс ConcurrentHashMap. Изображение 1399

31

Просто еще один ввод из моего собственного опыта с картами, когда я буду использовать каждый из них:

  • HashMap - наиболее полезно при поиске наилучшей (быстрой) реализации.
  • TreeMap (интерфейс SortedMap) - наиболее полезно, когда я заинтересован в возможности сортировки или перебора ключей в определенном порядке, который я определяю.
  • LinkedHashMap - объединяет преимущества гарантированного заказа от TreeMap без увеличения стоимости поддержки TreeMap. (Это почти так же быстро, как HashMap). В частности, LinkedHashMap также обеспечивает отличную отправную точку для создания объекта Cache, переопределяя метод removeEldestEntry(). Это позволяет создать объект Cache, который может истекать с использованием определенных критериев, которые вы определяете.
  • 10
    Чтобы быть точным, TreeMap не поддерживает элементы в порядке. Держит ключи в порядке.
31

HashMap

  • Он имеет значения пары (ключи, значения)
  • НЕТ значений ключа дублирования
  • неупорядоченный несортированный
  • он позволяет использовать один нулевой ключ и более чем одно значение null

HashTable

  • то же, что и хэш-карта
  • он не разрешает нулевые ключи и нулевые значения

LinkedHashMap

  • Это упорядоченная версия реализации карты
  • На основе связанных списков и структур хеширования данных

TreeMap

  • Упорядоченная и отсортированная версия
  • на основе хэш-структур данных
  • 2
    Также HashTable синхронизируется. В любом случае, мне нравится ваш ответ, чистый и ясный.
14

HashMap абсолютно не гарантирует порядок итерации. Это может (и будет) даже полностью меняться при добавлении новых элементов. TreeMap будет выполнять итерацию в соответствии с "естественным порядком" ключей согласно их методу compareTo() (или внешнему источнику Компаратор). Кроме того, он реализует интерфейс SortedMap, который содержит методы, которые зависят от этого порядка сортировки. LinkedHashMap будет итерации в том порядке, в котором записи были помещены в карту

Посмотрите, как меняется производительность. Изображение 1400

Карта дерева, представляющая собой реализацию Сортированной карты. Сложность операции put, get и containsKey - O (log n) из-за естественного упорядочения

10

Позвольте мне сказать просто:

  • HashMap реализован как хеш-таблица, и нет никаких заказов на клавиши или значения.
  • TreeMap реализуется на основе красно-черной древовидной структуры и упорядочивается клавишей.
  • LinkedHashMap сохраняет порядок вставки
  • Hashtable синхронизируется, в отличие от HashMap. Он имеет накладные расходы для синхронизации. Именно поэтому HashMap следует использовать, если программа является потокобезопасной.
9

@Amit: SortedMap - это интерфейс, тогда как TreeMap - это класс, реализующий интерфейс SortedMap. Это означает, что если следует протокол, который SortedMap просит своих исполнителей сделать. Дерево, если оно не реализовано как дерево поиска, не может дать вам упорядоченные данные, потому что дерево может быть любым деревом. Таким образом, чтобы заставить TreeMap работать как отсортированный порядок, он реализует SortedMap (например, дерево двоичного поиска - BST, сбалансированное BST, такое как дерево AVL и R-B, даже тройное дерево поиска - в основном используется для итеративных поисков упорядоченным способом).

public class TreeMap<K,V>
extends AbstractMap<K,V>
implements SortedMap<K,V>, Cloneable, Serializable

В NUT-SHELL HashMap: дает данные в O (1), без упорядочения

TreeMap: дает данные в O (log N), база 2. с упорядоченными клавишами

LinkedHashMap: есть таблица Hash со связанным списком (думаю, что проиндексирована-SkipList) возможность хранить данные так, как они вставлены в дерево. Лучше всего подходит для реализации LRU (в последнее время используется).

7

Все три класса HashMap, TreeMap и LinkedHashMap реализуют интерфейс java.util.Map и представляют собой сопоставление от уникального ключа к значениям.

HashMap

  • A HashMap содержит значения на основе ключа.

  • Он содержит только уникальные элементы.

  • Он может иметь один нулевой ключ и несколько нулевых значений.

  • Он поддерживает без порядка.

    public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

LinkedHashMap

  • A LinkedHashMap содержит значения, основанные на ключе.
  • Он содержит только уникальные элементы.
  • Он может иметь один нулевой ключ и несколько нулевых значений.
  • Это то же самое, что HashMap вместо этого поддерживает порядок вставки.//См. Ниже замедление класса

    public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

TreeMap

  • A TreeMap содержит значения, основанные на ключе. Он реализует интерфейс NavigableMap и расширяет класс AbstractMap.
  • Он содержит только уникальные элементы.
  • Он не может иметь нулевой ключ, но может иметь несколько нулевых значений.
  • То же, что и HashMap, поддерживает возрастающий порядок (Сортируется с использованием естественного порядка его ключа.).

    public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, Serializable

Hashtable

  • Hashtable - это массив списка. Каждый список известен как ведро. Положение ведра идентифицируется вызовом метода hashcode(). Hashtable содержит значения на основе ключа.
  • Он содержит только уникальные элементы.
  • Возможно, у него нет нулевого ключа или значения.
  • синхронизирован.
  • Это унаследованный класс.

    public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable

Изображение 1401

Ссылка: http://javarevisited.blogspot.in/2015/08/difference-between-HashMap-vs-TreeMap-vs-LinkedHashMap-Java.html

  • 0
    Обозначение Big-O в HashMap не должно быть O (1). Это лучший случай, и для хеш-таблиц в качестве наихудшего сценария используется O (n). Это подтверждается вашей ссылкой.
  • 0
    смотрите здесь - stackoverflow.com/questions/1055243/is-a-java-hashmap-really-o1/…
Показать ещё 6 комментариев
5

Это разные реализации одного и того же интерфейса. Каждая реализация имеет некоторые преимущества и некоторые недостатки (быстрая вставка, медленный поиск) или наоборот.

Подробнее см. javadoc TreeMap, HashMap, LinkedHashMap.

  • 0
    Что такое Hashtables на самом деле и чем он отличается от карты?
1

Все предлагают карту key- > value и способ перебирать ключи. Самое важное различие между эти классы - это гарантии времени и порядок ключей.

  • HashMap предлагает 0 (1) поиск и вставку. Однако, если вы перебираете ключи, упорядочение ключи по существу произвольны. Он реализуется массивом связанных списков.
  • TreeMap предлагает O (log N) поиск и вставку. Ключи упорядочены, поэтому, если вам нужно пройти через ключи в отсортированном порядке, вы можете. Это означает, что ключи должны реализовывать интерфейс Comparable.TreeMap реализуется красно-черным деревом.
  • LinkedHashMap предлагает 0 (1) поиск и вставку. Ключи упорядочиваются по порядку вставки. это реализуется двусвязными ведрами.

Представьте, что вы передали пустой TreeMap, HashMap и LinkedHashMap в следующую функцию:

void insertAndPrint(AbstractMap<Integer, String> map) {
  int[] array= {1, -1, 0};
  for (int x : array) {
    map.put(x, Integer.toString(x));
  }
  for (int k: map.keySet()) {
   System.out.print(k + ", ");
  }
}

Результат для каждого будет выглядеть следующим образом.

Для HashMap вывод был в моих собственных тестах {0, 1, -1}, но это может быть любой порядок. Нет гарантии на упорядоченность.
Treemap, результат был, {-1, 0, 1}
LinkedList, результат был, {1, -1, 0}

0

HashMap
может содержать один нулевой ключ.

HashMap не поддерживает порядок.

TreeMap

TreeMap не может содержать нулевой ключ.

TreeMap поддерживает восходящий порядок.

LinkedHashMap

LinkedHashMap может использоваться для поддержания порядка вставки, по которому ключи вставляются в Карту, или также может использоваться для поддержания порядка доступа, по которым доступны ключи.

Примеры::

1) HashMap map = new HashMap();

    map.put(null, "Kamran");
    map.put(2, "Ali");
    map.put(5, "From");
    map.put(4, "Dir");`enter code here`
    map.put(3, "Lower");
    for (Map.Entry m : map.entrySet()) {
        System.out.println(m.getKey() + "  " + m.getValue());
    } 

2) TreeMap map = new TreeMap();

    map.put(1, "Kamran");
    map.put(2, "Ali");
    map.put(5, "From");
    map.put(4, "Dir");
    map.put(3, "Lower");
    for (Map.Entry m : map.entrySet()) {
        System.out.println(m.getKey() + "  " + m.getValue());
    }

3) LinkedHashMap map = new LinkedHashMap();

    map.put(1, "Kamran");
    map.put(2, "Ali");
    map.put(5, "From");
    map.put(4, "Dir");
    map.put(3, "Lower");
    for (Map.Entry m : map.entrySet()) {
        System.out.println(m.getKey() + "  " + m.getValue());
    }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню