web-dev-qa-db-ja.com

JavaでのHashMapとArrayListの違いは?

Javaでは、ArrayListHashMapがコレクションとして使用されます。しかし、どの状況でArrayListを使用する必要があるか、またどのタイミングでHashMapを使用するかを理解できませんでした。両者の主な違いは何ですか?

43
Venkat

ArrayListとHashMapについて具体的に尋ねていますが、Collectionsフレームワークを理解するために何が起こっているかを完全に理解すると思います。したがって、ArrayListはListインターフェースを実装し、HashMapはMapインターフェースを実装します。したがって、本当の問題は、いつリストを使用し、いつマップを使用するかです。ここで、Java APIドキュメントが非常に役立ちます。

リスト:

順序付けられたコレクション(シーケンスとも呼ばれます)。このインターフェイスのユーザーは、リスト内の各要素が挿入される場所を正確に制御できます。ユーザーは、整数インデックス(リスト内の位置)で要素にアクセスし、リスト内の要素を検索できます。

地図:

キーを値にマッピングするオブジェクト。マップに重複キーを含めることはできません。各キーは最大で1つの値にマップできます。

したがって、他の回答で説明したように、リストインターフェイス(ArrayList)は、配列のようにインデックスを使用してアクセスするオブジェクトの順序付きコレクションです(ArrayListの場合、名前が示すように、それは単なる配列です)バックグラウンド、ただし、配列の処理の詳細の多くは自動的に処理されます)。ソートされた順序(追加される順序、または実際にオブジェクトを追加するときに指定したリスト内の位置)に物事を保持する場合は、ArrayListを使用します。

一方、Mapは1つのオブジェクトを取得し、それを別のオブジェクト(値)のキー(インデックス)として使用します。したがって、一意のIDを持つオブジェクトがあり、ある時点でこれらのオブジェクトにIDでアクセスすることを知っているとしましょう。マップにより、これが非常に簡単になります(より速く/より効率的になります)。 HashMap実装は、キーオブジェクトのハッシュ値を使用して、格納場所を特定するため、値の順序の保証はなくなりました。ただし、Java APIにはこれを提供できる他のクラスがあります。たとえば、LinkedHashMapは、ハッシュテーブルを使用してキー/値のペアを格納し、次のリスト(LinkedList)キーは追加された順序で追加されるため、追加された順序でアイテムにいつでもアクセスできます(必要な場合)。

78
DaveJohnston

ArrayListを使用する場合、インデックス(intタイプ)を使用して要素にアクセスする必要があります。 HashMapを使用すると、別のタイプのインデックス(たとえば、String)でそれらにアクセスできます。

HashMap<String, Book> books = new HashMap<String, Book>();
// String is the type of the index (the key)
// and Book is the type of the elements (the values)
// Like with an arraylist: ArrayList<Book> books = ...;

// Now you have to store the elements with a string key:
books.put("Harry Potter III", new Book("JK Rownling", 456, "Harry Potter"));

// Now you can access the elements by using a String index
Book book = books.get("Harry Potter III");

これはArrayListでは不可能です(またははるかに困難です)。 ArrayList内の要素にアクセスする唯一の良い方法は、インデックス番号で要素を取得することです。

したがって、これは、HashMapを使用すると、必要なすべてのタイプのキーを使用できることを意味します。

もう1つの役立つ例はゲームです。一連の画像があり、それらを反転させたい場合です。したがって、イメージフリップメソッドを記述し、反転した結果を保存します。

HashMap<BufferedImage, BufferedImage> flipped = new HashMap<BufferedImage, BufferedImage>();
BufferedImage player = ...; // On this image the player walks to the left.
BufferedImage flippedPlayer = flip(player); // On this image the player walks to the right.
flipped.put(player, flippedPlayer);
// Now you can access the flipped instance by doing this:
flipped.get(player);

プレーヤーを1回ひっくり返した後、保管します。 BufferedImageのキータイプとしてBufferedImageを使用して、HashMapにアクセスできます。

2番目の例を理解してください。

16

Java特定の質問ではありません。データ構造の「プライマー」が必要なようです。

このリンクを試してください http://www.devx.com/tips/Tip/14639

リンクから:

以下は、最も一般的に使用されるデータ構造を特定のニーズに合わせるためのいくつかのヒントです。

  1. ハッシュテーブルを使用する場合

保存されたデータにキーと値のペアの形式でアクセスする場合は、ハッシュテーブルまたは類似のデータ構造が適しています。たとえば、従業員の名前を取得する場合、結果はハッシュテーブルの形式で(名前、値)のペアとして返されます。ただし、複数の従業員の名前を返す場合、ハッシュテーブルを直接返すことはお勧めできません。キーは一意である必要があります。そうしないと、以前の値が上書きされます。

  1. リストまたはベクターを使用する場合

これは、シーケンシャルアクセスまたはランダムアクセスを希望する場合に適したオプションです。また、データサイズが最初は不明である場合、および/または動的に増加する場合は、リストまたはベクターを使用するのが適切です。たとえば、JDBC ResultSetの結果を保存するには、Java.util.LinkedListを使用できます。一方、サイズ変更可能な配列を探している場合は、Java.util.ArrayListクラスを使用します。

  1. 配列を使用する場合

配列を過小評価しないでください。ほとんどの場合、オブジェクトのリストを使用する必要がある場合、ベクターまたはリストの使用を検討する傾向があります。ただし、コレクションのサイズが既知であり、変更されない場合、配列は潜在的なデータ構造と見なすことができます。配列の要素へのアクセスは、ベクトルやリストよりも高速です。必要なのはインデックスだけだからです。追加のgetメソッド呼び出しのオーバーヘッドはありません。

4.組み合わせ

場合によっては、上記のアプローチを組み合わせて使用​​するのが最善かもしれません。たとえば、特定のニーズに合わせてハッシュテーブルのリストを使用できます。

  1. クラスを設定する

また、JDK 1.2以降では、Java.util.TreeSetなどのセットクラスもあります。これは、重複のないソートされたセットに役立ちます。これらのクラスの最も優れた点の1つは、特定のインターフェイスをすべて順守しているため、実際に仕様を心配する必要がないことです。たとえば、次のコードを見てください。

  // ...
  List list = new ArrayList();
  list.add(
14
Kannan Ekanath

値だけの順序付けられたコレクションのリストを使用します。たとえば、処理するファイルのリストがある場合があります。

キーから値への(通常は順序付けられていない)マッピングにマップを使用します。たとえば、ユーザーIDからそのユーザーの詳細へのマップがある場合、IDだけで詳細を効率的に見つけることができます。 (あなたはcouldキーのリストと値のリストを保存するだけでMapインターフェースを実装しますが、一般的にはより効率的な実装があります-HashMapは内部的に償却されるO(1)キールックアップなど)を取得するハッシュテーブル

4
Jon Skeet

地図とリスト。

マップには、キー/値のペアがあります。値にアクセスするには、キーを知る必要があります。キーと値の間には永続的な関係があり、任意ではありません。それらは何らかの形で関係しています。例:人物DNAは一意(キー)と人物名(値)または人物SSN(キー)と人物名(値)は強い関係があります。

リストでは、値(人の名前)だけがあり、それにアクセスするには、リスト内の位置(インデックス)を知ってからアクセスする必要があります。しかし、リスト内の値の位置とそのインデックスの間に永続的な関係はありません。それは任意です。

4
maxmcbyte