Saya memiliki array 2D dari Integer. Saya ingin mereka dimasukkan ke dalam HashMap. Tapi saya ingin mengakses elemen dari HashMap berdasarkan Array Index. Sesuatu seperti:
Untuk A [2] [5], map.get(2,5)
yang mengembalikan nilai yang terkait dengan kunci itu. Tapi bagaimana cara membuat hashMap dengan sepasang kunci? Atau secara umum, beberapa kunci: Map<((key1, key2,..,keyN), Value)
dengan cara yang saya dapat mengakses elemen dengan menggunakan get (key1, key2, ... keyN).
EDIT: 3 tahun setelah memposting pertanyaan, saya ingin menambahkan sedikit lebih banyak
Saya menemukan cara lain untuk NxN matrix
.
Indeks array, i
dan j
dapat direpresentasikan sebagai satu key
cara berikut:
int key = i * N + j;
//map.put(key, a[i][j]); // queue.add(key);
Dan indeks dapat ditarik kembali dengan key
cara ini:
int i = key / N;
int j = key % N;
Jawaban:
Ada beberapa pilihan:
2 dimensi
Peta peta
Objek kunci pembungkus
Menerapkan
equals()
danhashCode()
sangat penting di sini. Kemudian Anda cukup menggunakan:dan:
Table
dari jambu bijiTable
menggunakan peta peta di bawahnya.Dimensi N
Perhatikan bahwa
Key
kelas khusus adalah satu-satunya pendekatan yang diskalakan ke dimensi-n. Anda juga dapat mempertimbangkan:tapi itu mengerikan dari perspektif kinerja, serta keterbacaan dan ketepatan (bukan cara mudah untuk menerapkan ukuran daftar).
Mungkin lihat Scala di mana Anda memiliki tupel dan
case
kelas (mengganti seluruhKey
kelas dengan satu baris).sumber
Map.Entry<K, V>
sebagai kunci?Map<Pair<Key1, Key2>, Value>
?hashCode()
juga dapat diimplementasikan dengan satu baris sebagaiObjects.hash(x,y)
Saat Anda membuat objek pasangan kunci Anda sendiri, Anda harus menghadapi beberapa hal.
Pertama, Anda harus menyadari penerapan
hashCode()
danequals()
. Anda harus melakukan ini.Kedua, saat menerapkan
hashCode()
, pastikan Anda memahami cara kerjanya. Contoh pengguna yang diberikansebenarnya adalah salah satu penerapan terburuk yang dapat Anda lakukan. Alasannya sederhana: Anda memiliki banyak hash yang sama! Dan
hashCode()
harus mengembalikan nilai int yang cenderung langka, unik yang terbaik. Gunakan sesuatu seperti ini:Ini cepat dan mengembalikan hash unik untuk kunci antara -2 ^ 16 dan 2 ^ 16-1 (-65536 hingga 65535). Ini cocok di hampir semua kasus. Sangat jarang Anda berada di luar batasan ini.
Ketiga, ketika mengimplementasikan
equals()
juga tahu untuk apa itu digunakan dan menyadari bagaimana Anda membuat kunci Anda, karena mereka adalah objek. Seringkali Anda melakukan yang tidak perlu jika pernyataan menyebabkan Anda akan selalu mendapatkan hasil yang sama.Jika Anda membuat kunci seperti ini:
map.put(new Key(x,y),V);
Anda tidak akan pernah membandingkan referensi kunci Anda. Sebab setiap kali Anda ingin mengakses peta, Anda akan melakukan sesuatu sepertimap.get(new Key(x,y));
. Oleh karena itu Andaequals()
tidak membutuhkan pernyataan sepertiif (this == obj)
. Itu tidak akan pernah terjadi.Daripada
if (getClass() != obj.getClass())
Andaequals()
gunakan dengan lebih baikif (!(obj instanceof this))
. Ini akan berlaku bahkan untuk subclass.Jadi satu-satunya hal yang perlu Anda bandingkan sebenarnya adalah X dan Y. Jadi
equals()
penerapan terbaik dalam hal ini adalah:Jadi pada akhirnya kelas kunci Anda adalah seperti ini:
Anda dapat memberikan indeks dimensi
X
danY
tingkat akses publik, karena faktanya indeks tersebut final dan tidak berisi informasi sensitif. Saya tidak 100% yakin apakahprivate
tingkat akses berfungsi dengan benar dalam hal apa pun saat mentransmisikanObject
keKey
.Jika Anda bertanya-tanya tentang final, saya menyatakan apa pun sebagai final yang nilainya ditetapkan pada instancing dan tidak pernah berubah - dan oleh karena itu merupakan objek konstan.
sumber
Anda tidak dapat memiliki peta hash dengan banyak kunci, tetapi Anda dapat memiliki objek yang menggunakan banyak parameter sebagai kuncinya.
Buat sebuah objek bernama Indeks yang memiliki nilai x dan y.
Kemudian mintalah Anda
HashMap<Index, Value>
untuk mendapatkan hasil Anda. :)sumber
hashCode
danequals
.Diimplementasikan dalam koleksi umum MultiKeyMap
sumber
Dua kemungkinan. Gunakan salah satu kunci gabungan:
Atau Peta Peta:
sumber
hashCode
danequals
metode.Gunakan a
Pair
sebagai kunci untukHashMap
. JDK tidak memiliki Pair, tetapi Anda dapat menggunakan libraray pihak ketiga seperti http://commons.apache.org/lang atau menulis Pair taype Anda sendiri.sumber
Buat kelas nilai yang akan mewakili kunci majemuk Anda, seperti:
berhati-hati untuk mengganti
equals()
danhashCode()
dengan benar. Jika itu tampak seperti banyak pekerjaan, Anda dapat mempertimbangkan beberapa wadah generik siap pakai, seperti yangPair
disediakan oleh apache commons antara lain.Ada juga banyak pertanyaan serupa di sini, dengan ide lain, seperti menggunakan Tabel Jambu , meskipun memungkinkan kunci memiliki jenis yang berbeda, yang mungkin berlebihan (dalam penggunaan memori dan kompleksitas) dalam kasus Anda karena saya mengerti bahwa kunci Anda adalah bilangan bulat.
sumber
Jika keduanya adalah bilangan bulat, Anda dapat mencoba trik cepat dan kotor:
Map<String, ?>
menggunakan kunci sebagaii+"#"+j
.Jika kuncinya
i+"#"+j
sama denganj+"#"+i
cobamin(i,j)+"#"+max(i,j)
.sumber
String
dengan konsekuensi yang lucu.i#j = j#i
jikai == j
menggunakanmin/max
trik tidak akan berhasil.5#5
dan5#5
bertukar sekitar?5#3
memiliki hash yang sama3#5
, maka Anda menggunakan min / max untuk menegakkan3#5
urutan ini.Anda juga dapat menggunakan implementasi Tabel jambu biji untuk ini.
Tabel mewakili peta khusus di mana dua kunci dapat ditentukan secara gabungan untuk merujuk ke satu nilai. Ini mirip dengan membuat peta peta.
sumber
Anda dapat membuat objek utama Anda seperti ini:
MapKey kelas publik {
}
Keuntungan dari ini adalah: Ini akan selalu memastikan Anda mencakup semua skenario Equals juga.
CATATAN : Key1 dan key2 Anda harus tetap. Hanya dengan demikian Anda dapat membangun Objek kunci stabil.
sumber
kita dapat membuat kelas untuk melewatkan lebih dari satu kunci atau nilai dan objek kelas ini dapat digunakan sebagai parameter di peta.
sumber
Anda dapat mengunduhnya dari tautan di bawah ini: https://github.com/VVS279/DoubleKeyHashMap/blob/master/src/com/virtualMark/doubleKeyHashMap/DoubleKeyHashMap.java
https://github.com/VVS279/DoubleKeyHashMap
Anda dapat menggunakan kunci ganda: nilai hashmap,
sumber