HashMap、LinkedHashMap、TreeMapの違い


958

違いは何ですかHashMapLinkedHashMapTreeMapJavaでは?私はすべての3つのように、出力の違いをしている見ないkeySetvaluesHashtables とは何ですか?

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());

回答:


1160

3つのクラスすべてがMapインターフェースを実装し、ほとんど同じ機能を提供します。最も重要な違いは、エントリの反復が行われる順序です。

  • HashMap繰り返しの順序については一切保証しません。新しい要素が追加されると、完全に変更することもできます(変更されます)。
  • TreeMapそれらのcompareTo()方法(または外部から提供されたComparator)に応じたキーの「自然順序付け」に従って反復します。さらに、SortedMapこのソート順に依存するメソッドを含むインターフェースを実装します。
  • LinkedHashMap エントリがマップに配置された順序で反復します

「ハッシュテーブル」はハッシュベースのマップの総称です。Java APIのコンテキストでは Hashtable、コレクションフレームワークが存在する前のJava 1.1の時代からの時代遅れのクラスです。APIが機能を複製する古いメソッドでいっぱいになり、そのメソッドが同期されるため(パフォーマンスを低下させる可能性があり、通常は役に立たないため)、これはもう使用しないでください。Hashtableの代わりにConcurrentHashMapを使用してください。


2
実際にMapとは何か、Map、HashMapとHashtablesの違いは何か。
ケビン

5
@theband:マップはインターフェースです。HashMapとHashtableの両方がそれを実装しています。私が書いたように、Hashtableはレガシークラスです。
Michael Borgwardt、

98
間の顕著な違いHashtableとはHashMapHashtableに、「キーや値でもないがNULLとなる可能性がある」ということです。この制約は後者には存在しません。
aioobe

4
@AshkanN:はい-実際、これらはソートを実装する標準的な方法です。TreeMapには、Comparatorを使用するコンストラクターがあり、何も提供されない場合、追加されたすべてのオブジェクトがComparableを実装することを期待します。
Michael Borgwardt 2013

4
LinkedHashMapの反復を挿入順またはアクセス順のどちらにするかを選択できます。
lbalazscs 2014

1607

私は視覚的な表現を好む:

╔══════════════╦═════════════════════╦═══════════════════╦═════════════════════╗
║   Property   ║       HashMap       ║      TreeMap      ║     LinkedHashMap   ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║ Iteration    ║  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               ║
╚══════════════╩═══════════════════════════════════════════════════════════════╝

14
挿入順序に加えて、LinkedHashMapはアクセス順序もサポートしています(ブールアクセス順序パラメーターでコンストラクターを使用する場合)。
Eyal Schneider 2014

5
二重リンクバケット?挿入/削除操作のためにバケットを検索するという不要なオーバーヘッドが追加されると思います(オブジェクトを入れるために正しいバケットを検索する必要があるためです)。LinkedHashMapの実装はMapの実装に似ていると常に思っていましたが、反復目的で使用される「エントリリスト」(リンクリストの場合もあります)のオーバーヘッドが少し増えました。よろしい、シェブチク?はいの場合、あなたの声明を裏付けるいくつかのオンラインリンクを説明または教えてもらえますか?
サイダバカ2014

5
@SaiDubbaka LinkedHashMapには二重リンクバケットがありますが、バケットテーブルHashMapにもあります。それを置き換えるものではありません。これは、リンクされたリストが挿入順(またはアクセス順)のみの反復のために存在するため、バケットへのアクセスはHashMapと同じ方法で行われることを意味します。
Gerardo Lastra、2015年

5
言及する価値があるかもしれませんが、O(1)が最良のシナリオ(通常、Oとは呼ばないでしょう。この質問を参照してください)
Sebastian S

4
また、O(1)が常にO(log n)よりも優れているとは限らないことにも注意してください。キーが非常に長い場合、BSTに基づくものは、何かを実行する前にキー全体でO(n)ハッシュを実行する必要があるものよりもはるかに高速です。
モニカの訴訟に資金を

65

3つすべてが一意のキーから値へのマッピングを表すため、Mapインターフェースを実装します。

  1. HashMapは、キーのハッシュに基づくマップです。O(1)get / put操作をサポートします。これが機能するためにhashCode()equals()キーの一貫した実装が必要です。

  2. LinkedHashMapはHashMapに非常に似ていますが、アイテムが追加(またはアクセス)される順序が認識されるため、反復順序は挿入順序(または構築パラメーターに応じてアクセス順序)と同じです。

  3. TreeMapは、ツリーベースのマッピングです。そのput / get操作にはO(log n)時間かかります。アイテムには、ComparableまたはComparatorを使用した比較メカニズムが必要です。反復順序はこのメカニズムによって決定されます。


1
だから私が正しく理解すれば、LinkedHashMapとTreeMapの唯一の違いは、挿入の順序が自然な順序と同じである場合のパフォーマンスです。
モシェシャハム

19
@MosheShaham#2で述べたようにLinkedHashMap、自然順序ではなく挿入順序で反復します。したがって、(2,5,3)aに追加してLinkedHashMap、それぞれに対してaを実行すると、が返され2,5,3ます。それが2,5,3a だった場合、TreeMapそれは戻り2,3,5ます。
2013年

2
ツリーマップには、他にもたくさんの素晴らしいトリックがあります。頭と尾のマップのように。
トーマスアーレ2014年

プライベートTreeMap <String、Integer> mySection2 = new TreeMap <>(); mySection2.put( "abc1"、2); mySection2.put( "abc2"、5); mySection2.put( "abc3"、3); for(Integer x:mySection2.values()){Log.e( "LOG"、 "TreeMap ====" + x); これにより、アイテムが挿入されたのと同じ順序が得られます。LinkedHashMapsとの違いを教えてください。
B.shruti 2017年

2
@ B.shruti:これは、挿入順序がキーの辞書式順序( "abc1"、 "abc2"、 "abc3")と一致するためです。別の順序で挿入した場合でも、コードは辞書式順序に従って繰り返されます。
Eyal Schneider

47

次の図(大きい方)で、各クラスがクラス階層のどこにあるかを確認してください。TreeMapは実装しますがSortedMap、実装NavigableMapHashMapません。

HashTable廃止され、対応するConcurrentHashMapクラスを使用する必要があります。 ここに画像の説明を入力してください


38

HashMap

  • ペアの値(キー、値)があります
  • 重複キー値なし
  • 並べ替えなし
  • 1つのnullキーと複数のnull値を許可します

ハッシュ表

  • ハッシュマップと同じ
  • nullキーとnull値は許可されません

LinkedHashMap

  • マップ実装の注文バージョンです
  • リンクリストとハッシュデータ構造に基づく

TreeMap

  • 並べ替えられたバージョン
  • ハッシュデータ構造に基づく

3
また、HashTableも同期されます。とにかく、私はあなたの答えが好きです。
Surasin Tancharoen 2015

35

私がマップを使用するときの、マップに関する私自身の経験からのもう少しの入力:

  • HashMap-最高のパフォーマンス(高速)実装を探すときに最も役立ちます。
  • TreeMap(SortedMapインターフェース)-定義した特定の順序でキーをソートまたは反復できることに関心がある場合に最も役立ちます。
  • LinkedHashMap-TreeMapを維持するためのコストを増やすことなく、TreeMapからの保証された順序付けの利点を組み合わせます。(HashMapとほぼ同じ速度です)。特に、LinkedHashMapは、removeEldestEntry()メソッドをオーバーライドしてCacheオブジェクトを作成するための優れた出発点にもなります。これにより、定義した基準を使用してデータを期限切れにすることができるCacheオブジェクトを作成できます。

10
正確には、TreeMapは要素を順序どおりに保持しません。それはキーを順番に保ちます。
LS

17

3つのクラスHashMapはすべて、インターフェースTreeMapLinkedHashMap実装しjava.util.Map、一意のキーから値へのマッピングを表します。

HashMap

  1. AにHashMapは、キーに基づく値が含まれています。

  2. ユニークな要素のみが含まれています。

  3. 1つのnullキーと複数のnull値がある場合があります。

  4. それは秩序を維持しません

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

LinkedHashMap

  1. LinkedHashMapは、キーに基づく値が含まれています。
  2. ユニークな要素のみが含まれています。
  3. 1つのnullキーと複数のnull値がある場合があります。
  4. これはHashMapと同じで、代わりに挿入順序を維持します。//以下のクラスの減速を参照してください

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

TreeMap

  1. TreeMapは、キーに基づく値が含まれます。NavigableMapインターフェースを実装し、AbstractMapクラスを拡張します。
  2. ユニークな要素のみが含まれています。
  3. nullキーを持つことはできませんが、複数のnull値を持つことができます。
  4. HashMap代わりに昇順を維持するのと同じです(キーの自然順序を使用してソートされます)。

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

ハッシュ表

  1. Hashtableはリストの配列です。各リストはバケットと呼ばれます。バケットの位置は、hashcode()メソッドを呼び出すことによって識別されます。Hashtableには、キーに基づく値が含まれています。
  2. ユニークな要素のみが含まれています。
  3. nullキーまたは値がない場合があります。
  4. それはされて同期
  5. レガシークラスです。

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

参照:http : //javarevisited.blogspot.in/2015/08/difference-between-HashMap-vs-TreeMap-vs-LinkedHashMap-Java.html


HashMapのBig-O表記はO(1)であってはなりません。それが最良のケースであり、ハッシュテーブルは最悪のシナリオとしてO(n)を持っています。これはリンクでサポートされています。
HaakonLøtveit2017


HaakonLøtveit私もここで実際のコードのために行くことをお勧めします@ - grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/...
roottraveller

そのSTILLは、最悪の場合はO(n)だと言っています。これは数学的概念であり、実際にO(1)でない限り、O(1)であるとは言えません。ここでは、本当に優れたハッシュ関数もいくつか想定しています。つまり、クラスTerribleHashKey {@Override hashCode(){return 4; / *公正なサイコロ投げ* /}}によって決定され、それを他の楽しいもののキーとして使用します。O(1)の可能性が高いこととO(1)があることは同じではありません。人々は宿題を手伝うためにここに来ます。彼らの成績を台無しにしましょう..;)
HaakonLøtveit2017

また、Java 8では、8個を超えるバケットがある場合、O(log(n))の最悪のケースがあることに注意してください。grepcode.com/ file / repository.grepcode.com / java / root / jdk / openjdkを参照してください。 /…この詳細については。
HaakonLøtveit2017

14

HashMapは、反復順序について絶対に保証するものではありません。新しい要素が追加されると、完全に変更することもできます(変更されます)。TreeMapは、compareTo()メソッド(または外部から提供されるコンパレータ)に従って、キーの「自然な順序」に従って反復します。また、この並べ替え順序に依存するメソッドを含むSortedMapインターフェイスを実装します。LinkedHashMapは、エントリがマップに配置された順序で反復します

パフォーマンスの変化を見てください。 ここに画像の説明を入力してください

ソートされたマップの実装であるツリーマップ。Naturalの順序付けにより、put、get、containsKey操作の複雑さはO(log n)です。


9

@Amit:SortedMapはインターフェースですが、インターフェースTreeMapを実装するクラスSortedMapです。これSortedMapは、実装者に要求するプロトコルに従う場合に意味します。ツリーは検索ツリーとして実装されていない限り、順序付けされたデータを提供できません。そのため、TreeMapをSortedMapのように機能させるために、SortedMapを実装します(たとえば、Binary Search Tree-BST、AVLやRB TreeのようなバランスのとれたBST、Ternary Search Treeも-主に順序付けされた方法で反復検索に使用されます)。

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

NUT-SHELLの場合 HashMap:O(1)でデータを提供し、順序付けなし

TreeMap :O(log N)、base 2のデータを提供します。順序付きキーを使用します

LinkedHashMap:は、ツリーに挿入される方法でデータを格納するためのリンクリスト(indexed-SkipListと考える)機能を持つハッシュテーブルです。LRUの実装に最も適しています(最近使用されていない)。


6

HashMapとTreeMapの主な違いは次のとおりです

  1. HashMapは順序を維持しません。つまり、HashMapでは、最初に挿入された要素が最初に印刷されるという保証はありません。TreeSet要素と同様に、TreeMap要素もその要素の自然な順序に従って並べ替えられます。

  2. 内部HashMap実装はハッシュを使用し、TreeMapは内部的にRed-Blackツリー実装を使用します。

  3. HashMapは1つのnullキーと多くのnull値を格納できます。TreeMapはnullキーを含むことはできませんが、多くのnull値を含むことができます。

  4. HashMapは、getおよびputのような基本的な操作、つまりO(1)に対して一定の時間パフォーマンスを発揮します。Oracledocsによると、TreeMapは、getおよびputメソッドに対して保証されたlog(n)時間コストを提供します。

  5. ほとんどの操作では、HashMapのパフォーマンス時間はログ時間TreeMapに対して一定であるため、HashMapはTreeMapよりもはるかに高速です。

  6. HashMapは比較でequals()メソッドを使用し、TreeMapは順序を維持するためにcompareTo()メソッドを使用します。

  7. HashMapはMapインターフェースを実装し、TreeMapはNavigableMapインターフェースを実装します。



5

ハッシュマップは挿入順序を保持しません。
例。ハッシュマップとしてキーを挿入する場合

1  3
5  9
4   6
7   15
3   10

として保存できます

4  6
5  9
3  10
1  3
7  15

リンクされたハッシュマップは挿入順序を保持します。

例。
キーを挿入する場合

1  3
5  9
4   6
7   15
3   10

として保存します

1  3
5  9
4   6
7   15
3   10

挿入と同じです。

ツリーマップは、値をキーの昇順で格納します。例。
キーを挿入する場合

1  3
5  9
4   6
7   15
3   10

として保存します

1  3
3  10
4   6
5   9
7   15

4
  • HashMap:

    • 注文は維持されません
    • LinkedHashMapよりも高速
    • オブジェクトのストアヒープに使用
  • LinkedHashMap:

    • LinkedHashMapの挿入順序は維持されます
    • HashMapより遅く、TreeMapより速い
    • 広告掲載オーダーを維持したい場合は、これを使用してください。
  • TreeMap:

    • TreeMapはツリーベースのマッピングです
    • TreeMapはキーの自然な順序に従います
    • HashMapおよびLinkedHashMapより遅い
    • 自然な(デフォルトの)順序を維持する必要がある場合は、TreeMapを使用します

1

すべてがキーと値のマップを提供し、キーを反復処理する方法を提供します。これらのクラスの最も重要な違いは、時間の保証とキーの順序です。

  1. HashMapは0(1)の検索と挿入を提供します。ただし、キーを反復処理する場合、キーの順序は基本的に任意です。リンクされたリストの配列によって実装されます。
  2. TreeMapはO(log N)ルックアップと挿入を提供します。キーは順序付けされているので、キーをソートされた順序で反復する必要がある場合は可能です。つまり、キーはComparableインターフェースを実装する必要があります。TreeMapは赤黒ツリーによって実装されます。
  3. 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}


1

ここには優れた答えがたくさんありますが、MapJava 11にバンドルされているさまざまな実装を説明した独自の表を提示したいと思います。

表のグラフィックにこれらの違いが一覧表示されています。

  • HashMapある汎用 Mapあなたは特別なニーズを持っていないときに一般的に使用されます。
  • LinkedHashMap拡張HashMap、この動作の追加:順序、つまりエントリが最初に追加された順序を維持します。Key-Valueエントリの値を変更しても、順序の場所は変わりません。
  • TreeMapあまりにも順序を維持しますが、(a)「自然な」順序、つまりインターフェースでcompareTo定義されたキーオブジェクトのメソッドの値を使用するかComparable、(b)指定しComparator実装を呼び出します。
    • TreeMapSortedMapインターフェースとその後継であるNavigableMapインターフェースの両方を実装します。
  • NULL S:TreeMapないないキーとしてNULLを許可しながら、HashMapLinkedHashMap行います。
    • 3つとも、値としてNULLを許可します。
  • HashTableあるレガシー Javaの1から、ConcurrentHashMapクラスに取って代わられました。Javadocを引用するとConcurrentHashMap、と同じ機能仕様に従い、のHashtable各メソッドに対応するメソッドのバージョンが含まれますHashtable

Java 11のマップ実装の表、それらの機能の比較


0

HashMap
は1つのnullキーを含めることができます。

HashMapは順序を維持しません。

TreeMap

TreeMapにnullキーを含めることはできません。

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());
    }

0

3つすべての中で最も重要なのは、エントリの順序を保存する方法です。

HashMap-エントリの順序は保存されません。例えば。

public static void main(String[] args){
        HashMap<String,Integer> hashMap = new HashMap<>();
        hashMap.put("First",1);// First ---> 1 is put first in the map
        hashMap.put("Second",2);//Second ---> 2 is put second in the map
        hashMap.put("Third",3); // Third--->3 is put third in the map
        for(Map.Entry<String,Integer> entry : hashMap.entrySet())
        {
            System.out.println(entry.getKey()+"--->"+entry.getValue());
        }
    }

HashMapの出力

LinkedHashMap:エントリが作成された順序を保存します。例えば:

public static void main(String[] args){
        LinkedHashMap<String,Integer> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("First",1);// First ---> 1 is put first in the map
        linkedHashMap.put("Second",2);//Second ---> 2 is put second in the map
        linkedHashMap.put("Third",3); // Third--->3 is put third in the map
        for(Map.Entry<String,Integer> entry : linkedHashMap.entrySet())
        {
            System.out.println(entry.getKey()+"--->"+entry.getValue());
        }
    }

LinkedHashMapの出力

TreeMap:キーの昇順でエントリを保存します。例えば:

public static void main(String[] args) throws IOException {
        TreeMap<String,Integer> treeMap = new TreeMap<>();
        treeMap.put("A",1);// A---> 1 is put first in the map
        treeMap.put("C",2);//C---> 2 is put second in the map
        treeMap.put("B",3); //B--->3 is put third in the map
        for(Map.Entry<String,Integer> entry : treeMap.entrySet())
        {
            System.out.println(entry.getKey()+"--->"+entry.getValue());
        }
    }

TreeMapの出力

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.