キーとしてのHashMapおよびint


104

キーとして整数、値としてオブジェクトを持つHas​​hMapを構築しようとしています。

私の構文は:

HashMap<int, myObject> myMap = new HashMap<int, myObject>();

ただし、返されるエラーは次のとおりです-トークン「int」の構文エラー、このトークンの後に予期されるディメンション-数字を格納するだけでよいので、ディメンションを追加する必要がある理由(つまり、intを配列にする)がわかりませんキーとして。

私は何ができますか?

前もって感謝します!:)


14
HashMapプリミティブは処理せず、オブジェクトのみを処理します。
Menno 2013

関連するSOの質問ですがint、価値ではなく、キーです。
cyroxx 2013

5
Integer代わりに使用してください。
Hot Licks 2013

整数を整数にオートボックス化するか、データを文字列として格納する方が快適ですか?
Marcin Erbel 2016

回答:


25

HashMapはキーの内部でオブジェクトを使用するため、プリミティブは使用できません。したがって、オブジェクトから継承したオブジェクト(つまり、任意のオブジェクト)のみを使用できます。

これはHashMapのput()関数であり、ご覧のとおり、Kのオブジェクトを使用しています。

public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

「k = e.key」という表現は、それを明確にするはずです。

Integerやautoboxingのようなラッパーを使用することをお勧めします。


137

Integer代わりに使用してください。

HashMap<Integer, MyObject> myMap = new HashMap<Integer, MyObject>();

Javaは自動的にintプリミティブ値をIntegerオブジェクトにオートボックス化します。

オートボクシングの詳細については、Oracle Javaのドキュメントをご覧ください。


10
彼はまた、クラス名はならないmyObject
アダム・ゲント

@AdamGent正解。すべてのクラス名は大文字で始める必要があります。推奨コードを修正しました。
gaborsch 2013

3
私はあなたが知っていることを知っています:) OPが知っている/学ぶことを確認したいだけです。彼が型パラメーターに変数名を入れていた可能性があることはすべて知っています。
アダム・ゲント

1
メモリを節約し、パフォーマンスを向上させるには、ArrayMapまたはSimpleArrayMapAndroid を使用すること
Noah Huppert

42

Androidデバイス用にJavaをコーディングし、ここで終了するすべての人にとって:SparseArrayパフォーマンスを向上させるために使用します。

private final SparseArray<myObject> myMap = new SparseArray<myObject>();

これにより、Integerの代わりにintを使用できます。

int newPos = 3;

myMap.put(newPos, newObject);
myMap.get(newPos);

7
SparseArrayはハッシュマップよりも低速ですが、メモリ効率は向上します。したがって、大きなデータセットでは使用しないでください。
TpoM6oH 2014年

SparseArrayを使用して、パフォーマンスを低下させながらパフォーマンスを向上させる方法を教えてください。私のAndroidゲームでどちらを使用するか
Snake

@SnakeのSparseArray場合と同様に、メモリのボクシングとアンボクシングのintの束を割り当てる場合、VM HashMapはガベージコレクションの実行をより早く一時停止する必要があります。これは、何かを頻繁かつ迅速に行う場合に重要です。
Jon

1
挿入の複雑さを覚えSparseArrayているO(N) HashMap持つO(1) )。要素数が多い場合に重要です。このような配列の先頭への挿入は非常に遅くなります。
Vladimir Petrakovich 2017年

1
@ M.kazemAkhgary正確ではありません。put()かかるO(n)(ないn log n、それは位置を検出し、すべての次の要素を移動させるため、開始時の挿入のため)。delete()それ自体は確かにかかりますがO(log n)、削除後の要素の次の挿入または反復には、取るガベージコレクションが必要になりますO(n)
Vladimir Petrakovich


4

主な理由のHashMapのキーとしてプリミティブ許可しないハッシュマップがキーを比較するために、それはの使用なるように設計されていることである)に等しいと(方法、及びこの方法のみではないプリミティブ上のオブジェクト上に呼び出すことができます。

したがって、intがIntegerにオートボックス化されている場合、HashmapはIntegerオブジェクトのequals()メソッドを呼び出すことができます。

そのため、intの代わりにIntegerを使用する必要があります。私はハッシュマップがintをキーとして入れているときにエラーをスローすることを意味します(スローされるエラーの意味がわかりません)

そして、もしあなたがプリミティブをキーとして作ることによってマップのパフォーマンスをより速くすることができると思うなら、キーとしてint型を持つマップ実装を含むFastUtilと呼ばれるライブラリがあります。

このため、ハッシュマップよりもはるかに高速です


1
いいえ、プリミティブ型を許可しないための主な理由は、型消去効果的になり、Javaで、Map<Integer, String>Map<Object, Object>コンパイル時に。ところで、==等価性チェックに演算子を使用するIdentityHashMapがありますが、それでもプリミティブ型は許可されていません。
Yoory N.

3

HashMapでは、プリミティブデータ型を引数として使用できません。オブジェクトのみを受け入れることができるので

HashMap<int, myObject> myMap = new HashMap<int, myObject>();

動作しないでしょう。

宣言を次のように変更する必要があります

HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();

次のようにしても

myMap.put(2,myObject);

プリミティブデータ型は、Integerオブジェクトにオートボックス化されます。

8 (int) === boxing ===> 8 (Integer)

オートボクシングの詳細については、http: //docs.oracle.com/javase/tutorial/java/data/autoboxing.htmlをご覧ください。


3

Androidでコーディングする場合、整数をオブジェクトにマッピングするSparseArrayがあります。


1

intをプリミティブ型としてではなくオブジェクトとして使用する

HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();

私はHashMap <Integer、MyObject> myMap = new HashMap <Integer、MyObject>();と書きました。しかし、表示すると>と<で問題が発生し、適切な回答が表示されます
franki3xe 2013

入力するのは辛いのはわかっていますが、すぐに入力しないようにしようとしていました-1。私はペナルティを課す前に他のコメントとは異なります(私はあなたを-1にしませんでした)。
アダム・ゲント

0

使ってください HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();


0

数字をキーとして格納するだけでよいので、なぜ次元を追加する必要があるのか​​(つまり、intを配列にする必要がある)がわかりません。

配列もオブジェクトHashMap<int[], MyObject>なので、int配列をキーとして使用する有効な構成体です。

コンパイラーは、ユーザーが何を必要としているか、何が必要かを認識していません。ほぼ正しい言語構造を認識し、不足しているものを完全に正しいと警告します。


1
これに注意してください。配列のハッシュ値はその内容とは関係がないため、同じ内容の2つの配列が異なる値にハッシュされ、非常に貧弱なキーになる可能性があります。
john16384

0

プリミティブ型に対するラッパーのJavaでのオートボクシングのフットプリントを削減したいので、そのようなマップに興味がある人は、Eclipseコレクションを使用することをお勧めします 。Troveはもうサポートされていません。それは(とにかくかなり人気がありますが)非常に信頼性の低いライブラリであり、Eclipseコレクションと比較できなかったと思います。

import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap;

public class Check {
    public static void main(String[] args) {
        IntObjectHashMap map = new IntObjectHashMap();

        map.put(5,"It works");
        map.put(6,"without");
        map.put(7,"boxing!");

        System.out.println(map.get(5));
        System.out.println(map.get(6));
        System.out.println(map.get(7));
    }
}

上記の例ではIntObjectHashMapです。

int-> objectマッピングが必要な場合は、YourObjectType[]配列の使用を考慮してください。またList<YourObjectType>、マップは本質的に、int型をインデックスとする連想配列であるため、インデックスによる値のアクセスも検討してください。

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