Jika saya memiliki nilai "foo"
, dan nilai HashMap<String> ftw
yang ftw.containsValue("foo")
kembali true
, bagaimana saya bisa mendapatkan kunci yang sesuai? Apakah saya harus mengulang hashmap? Apa cara terbaik untuk melakukannya?
450
public static final String TIME = "time";
danproperties.put(TIME, PbActivityJpa_.time);
Jawaban:
Jika Anda memilih untuk menggunakan pustaka Commons Collections alih-alih API Java Collections standar, Anda dapat melakukannya dengan mudah.
The BidiMap antarmuka di perpustakaan Koleksi adalah peta bi-directional, yang memungkinkan Anda untuk memetakan kunci untuk nilai (seperti peta normal), dan juga untuk memetakan nilai untuk kunci, sehingga memungkinkan Anda untuk melakukan pencarian di kedua arah. Mendapatkan kunci untuk suatu nilai didukung oleh metode getKey () .
Namun ada peringatan, peta bidi tidak dapat memiliki beberapa nilai yang dipetakan ke kunci, dan karenanya kecuali kumpulan data Anda memiliki pemetaan 1: 1 antara kunci dan nilai, Anda tidak dapat menggunakan bidimaps.
Memperbarui
Jika Anda ingin mengandalkan Java Collections API, Anda harus memastikan hubungan 1: 1 antara kunci dan nilai pada saat memasukkan nilai ke dalam peta. Ini lebih mudah dikatakan daripada dilakukan.
Setelah Anda bisa memastikannya, gunakan metode entrySet () untuk mendapatkan set entri (pemetaan) di Peta. Setelah Anda mendapatkan set yang jenisnya adalah Map.Entry , beralih melalui entri, membandingkan nilai yang disimpan dengan yang diharapkan, dan mendapatkan kunci yang sesuai .
Perbarui # 2
Dukungan untuk peta bidi dengan obat generik dapat ditemukan di Google Guava dan perpustakaan Commons-Collections refactored (yang terakhir bukan proyek Apache). Terima kasih kepada Esko untuk menunjukkan dukungan generik yang hilang di Apache Commons Collections. Menggunakan koleksi dengan obat generik membuat kode lebih mudah dikelola.
sumber
Jika struktur data Anda memiliki banyak-ke-satu pemetaan antara kunci dan nilai-nilai Anda harus mengulangi entri dan memilih semua kunci yang sesuai:
Dalam kasus hubungan satu-ke-satu , Anda dapat mengembalikan kunci yang cocok pertama:
Di Jawa 8:
Juga, untuk pengguna Guava, BiMap mungkin berguna. Sebagai contoh:
sumber
o(1)
. Jika Anda mengulangi nilai-nilai maka itu akan mematikan kinerja. Jika Anda menginginkanbetter performance
dan memilikione-one
hubungan, Anda dapat menggunakan dianother map
manavalue is a key
.filter(entry -> entry.getValue().equals(value))
dengan karena tidak ada pernyataan tentang kemampuan dibuat. Selanjutnya, Anda dapat mengganti dengan.filter(entry ->
Objects.equals
(entry.getValue(), value))
null
.map(entry -> entry.getKey())
.map(Map.Entry::getKey)
Beberapa info tambahan ... Semoga bermanfaat bagi Anda
Metode di atas mungkin tidak baik jika hashmap Anda benar-benar besar. Jika hashmap Anda berisi kunci unik untuk pemetaan nilai unik, Anda dapat mempertahankan satu hashmap lain yang berisi pemetaan dari Value to Key.
Itu adalah Anda harus mempertahankan dua hashmaps
Dalam hal ini Anda dapat menggunakan hashmap kedua untuk mendapatkan kunci.
sumber
Saya pikir pilihan Anda adalah
entrySet()
dan untuk menemukan kunci yang cocok dengan nilai. Ini adalah metode paling lambat, karena membutuhkan pengulangan melalui seluruh koleksi, sedangkan dua metode lainnya tidak memerlukan itu.sumber
Anda bisa memasukkan kunci, pasangan nilai dan kebalikannya ke dalam struktur peta Anda
Menggunakan map.get ("theValue") kemudian akan mengembalikan "theKey".
Ini cara cepat dan kotor yang saya buat peta konstan, yang hanya akan bekerja untuk beberapa set data tertentu:
sumber
Hiasi peta dengan implementasi Anda sendiri
sumber
Tidak ada jawaban yang jelas, karena beberapa kunci dapat memetakan ke nilai yang sama. Jika Anda menerapkan keunikan dengan kode Anda sendiri, solusi terbaik adalah membuat kelas yang menggunakan dua Hashmaps untuk melacak pemetaan di kedua arah.
sumber
Untuk menemukan semua kunci yang memetakan ke nilai itu, iterate melalui semua pasangan di hashmap, menggunakan
map.entrySet()
.sumber
Menggunakan Java 8:
sumber
value=="foo"
ini tidak akan berhasil.equals
harus digunakan untuk membandingkan Strings.value
telah diinternir.Jika Anda membangun peta dalam kode Anda sendiri, cobalah menyatukan kunci dan nilai dalam peta:
Kemudian ketika Anda memiliki nilai, Anda juga memiliki kuncinya.
sumber
Saya pikir ini adalah solusi terbaik, alamat asli: Java2s
Penggunaan yang mudah: jika Anda meletakkan semua data di hasMap dan Anda memiliki item = "Automobile", maka Anda mencari kuncinya di hashMap. itu solusi yang bagus.
sumber
Saya khawatir Anda hanya perlu mengulang peta Anda. Terpendek saya bisa datang dengan:
sumber
sumber
Kedengarannya cara terbaik bagi Anda adalah beralih dari entri
map.entrySet()
karenamap.containsValue()
mungkin tetap melakukan ini.sumber
Untuk API penargetan pengembangan Android <19, solusi hubungan satu-ke-satu Vitalii Fedorenko tidak berfungsi karena
Objects.equals
tidak diterapkan. Inilah alternatif sederhana:sumber
Anda dapat menggunakan di bawah ini:
sumber
Ya, Anda harus mengulang-ulang hashmap, kecuali Anda menerapkan sesuatu sesuai dengan apa yang disarankan oleh berbagai jawaban ini. Daripada mengutak-atik entriSet, saya hanya mendapatkan keySet (), beralih di set itu, dan simpan kunci (pertama) yang memberi Anda nilai kecocokan Anda. Jika Anda membutuhkan semua kunci yang cocok dengan nilai itu, jelas Anda harus melakukan semuanya.
Seperti yang disarankan Jonas, ini mungkin sudah menjadi apa yang dilakukan oleh metode containValue, jadi Anda bisa melewatkan tes itu bersama-sama, dan lakukan iterasi setiap kali (atau mungkin kompiler sudah akan menghilangkan redundansi, siapa tahu).
Juga, relatif terhadap jawaban lain, jika peta terbalik Anda terlihat seperti
Anda dapat menangani pemetaan nilai-kunci yang tidak unik, jika Anda membutuhkan kemampuan itu (mengesampingkannya). Itu akan memasukkan baik ke salah satu solusi yang disarankan orang di sini menggunakan dua peta.
sumber
Anda bisa mendapatkan kunci menggunakan nilai menggunakan kode berikut ..
sumber
sumber
String
kunci dan nilai. Ketika saya meneleponmap.add("1", "2"); map.add("1","3");
maka saya bisa meneleponmap.getKey("2");
dan mengambil"1"
, meskipun"1"
adalah kunci untuk"3"
.getValue("1")
akan kembali3
.Di java8
sumber
sumber
sumber
sumber
sumber
Gunakan pembungkus tipis: HMap
sumber
2 sen saya. Anda bisa mendapatkan kunci dalam array dan kemudian loop melalui array. Ini akan mempengaruhi kinerja blok kode ini jika peta cukup besar, di mana Anda mendapatkan kunci dalam array pertama yang mungkin memakan waktu dan kemudian Anda mengulang. Kalau tidak, untuk peta yang lebih kecil seharusnya ok.
sumber
Saya pikir keySet () mungkin lebih baik untuk menemukan pemetaan kunci ke nilai, dan memiliki gaya pengkodean yang lebih baik daripada entrySet () .
Ex:
Misalkan Anda memiliki peta HashMap , resolusi ArrayList , nilai yang ingin Anda temukan semua pemetaan kuncinya , kemudian simpan kunci ke res tersebut .
Anda dapat menulis kode di bawah ini:
daripada menggunakan entrySet () di bawah:
Semoga bermanfaat :)
sumber
map.get(key) == value
bukan ide yang baik ketika memeriksa kesamaan objek, karena Anda membandingkan referensi. Persamaan objek harus selalu menggunakan.equals()
Meskipun ini tidak langsung menjawab pertanyaan, itu terkait.
Dengan cara ini Anda tidak perlu terus membuat / mengulangi. Cukup buat peta terbalik sekali dan dapatkan yang Anda butuhkan.
sumber
Penting untuk dicatat bahwa sejak pertanyaan ini, Koleksi Apache mendukung BidiMaps Generik . Jadi, beberapa jawaban pilihan teratas tidak lagi akurat pada titik itu.
Untuk BidiMap Serial yang juga mendukung nilai duplikat (skenario 1-ke-banyak) juga mempertimbangkan MapDB.org .
sumber
Jika Anda ingin mendapatkan kunci dari nilai, yang terbaik untuk menggunakan bidimap (peta dua arah), Anda bisa mendapatkan kunci dari nilai dalam waktu O (1).
Tapi, kekurangannya adalah Anda hanya bisa menggunakan keyset dan valueset unik.
Ada struktur data yang disebut Tabel di java, yang tidak lain adalah peta seperti peta
Tabel <A, B, C> == peta <A, peta <B, C>>
Di sini Anda bisa mendapatkan
map<B,C>
dengan permintaanT.row(a);
, dan Anda juga bisa mendapatkanmap<A,C>
dengan permintaanT.column(b);
Dalam kasus khusus Anda, masukkan C sebagai konstanta.
Jadi, ini seperti <a1, b1, 1> <a2, b2, 1>, ...
Jadi, jika Anda menemukan melalui T.row (a1) ---> mengembalikan peta -> dapatkan keyset peta yang dikembalikan ini.
Jika Anda perlu menemukan nilai kunci, T.column (b2) -> mengembalikan peta -> mendapatkan keyset dari peta yang dikembalikan.
Keuntungan dari kasus sebelumnya:
sumber