Jawa Hashmap: Bagaimana untuk mendapatkan kunci dari nilai?

Jika saya memiliki nilai "anu", dan HashMap<String> ftw untuk yang ftw.containsValue("anu") mengembalikan true, bagaimana saya bisa mendapatkan tombol yang sesuai? Apakah saya harus loop melalui hashmap? Apa cara terbaik untuk melakukan itu?

Mengomentari pertanyaan (3)

Jika anda struktur data yang telah banyak-ke-satu pemetaan antara kunci dan nilai-nilai anda harus iterate atas entri dan mengambil semua kunci yang cocok:

public static  Set getKeysByValue(Map map, E value) {
    Set keys = new HashSet();
    for (Entry entry : map.entrySet()) {
        if (Objects.equals(value, entry.getValue())) {
            keys.add(entry.getKey());
        }
    }
    return keys;
}

Dalam kasus satu-ke-satu hubungan, anda dapat kembali pertama dicocokkan kunci:

public static  T getKeyByValue(Map map, E value) {
    for (Entry entry : map.entrySet()) {
        if (Objects.equals(value, entry.getValue())) {
            return entry.getKey();
        }
    }
    return null;
}

Di Jawa 8:

public static  Set getKeysByValue(Map map, E value) {
    return map.entrySet()
              .stream()
              .filter(entry -> Objects.equals(entry.getValue(), value))
              .map(Map.Entry::getKey)
              .collect(Collectors.toSet());
}

Juga, untuk Jambu pengguna, BiMap mungkin berguna. Misalnya:

BiMap tokenToChar = 
    ImmutableBiMap.of(Token.LEFT_BRACKET, '[', Token.LEFT_PARENTHESIS, '(');
Token token = tokenToChar.inverse().get('(');
Character c = tokenToChar.get(token);
Komentar (5)
Larutan

Jika anda memilih untuk menggunakan Commons Koleksi perpustakaan bukan standar Koleksi Java API, anda dapat mencapai hal ini dengan mudah.

The BidiMap antarmuka dalam Koleksi perpustakaan adalah bi-directional peta, 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 nilai ini didukung oleh getKey() metode.

Ada peringatan meskipun, bidi maps tidak dapat memiliki beberapa nilai dipetakan ke kunci, dan karenanya kecuali data set 1:1 pemetaan antara kunci dan nilai-nilai, anda tidak dapat menggunakan bidimaps.

Update

Jika anda ingin bergantung pada Koleksi Java API, anda akan memiliki untuk memastikan hubungan 1:1 antara kunci dan nilai-nilai pada saat memasukkan nilai ke dalam peta. Ini lebih mudah dikatakan daripada dilakukan.

Setelah anda dapat memastikan bahwa, gunakan entrySet() metode untuk mendapatkan set entri (pemetaan) di Peta. Setelah anda telah memperoleh himpunan yang jenis Peta.Entri, iterate melalui entri, membandingkan nilai yang disimpan terhadap yang diharapkan, dan mendapatkan tombol.

Update #2

Dukungan untuk bidi peta dengan obat generik dapat ditemukan di Google Jambu dan refactored Commons-Koleksi perpustakaan (yang terakhir ini tidak Apache proyek). Terima kasih untuk Esko untuk menunjuk hilang generik dukungan di Apache Commons Koleksi. Menggunakan koleksi dengan obat generik membuat lebih maintainable kode.

Komentar (8)
public class NewClass1 {

    public static void main(String[] args) {
       Map testMap = new HashMap();
        testMap.put(10, "a");
        testMap.put(20, "b");
        testMap.put(30, "c");
        testMap.put(40, "d");
        for (Entry entry : testMap.entrySet()) {
            if (entry.getValue().equals("c")) {
                System.out.println(entry.getKey());
            }
        }
    }
}

Beberapa info tambahan... Mungkin berguna untuk anda

Metode di atas mungkin tidak akan baik jika anda hashmap adalah benar-benar besar. Jika anda hashmap mengandung kunci yang unik untuk menawarkan nilai yang unik untuk pemetaan, anda dapat mempertahankan satu lagi hashmap yang berisi pemetaan dari Nilai Key.

Yang anda harus mempertahankan dua hashmaps

1. Key to value

2. Value to key 

Dalam hal ini anda dapat menggunakan kedua hashmap untuk mendapatkan kunci.

Komentar (0)

Saya pikir pilihan anda

  • Gunakan peta pelaksanaan dibangun untuk ini, seperti BiMap dari google koleksi. Perhatikan bahwa google koleksi BiMap membutuhkan uniqueless dari nilai-nilai, serta tombol, tetapi memberikan kinerja tinggi di kedua arah kinerja
  • Manual mempertahankan dua peta - satu untuk kunci -> nilai, dan lain peta untuk nilai -> kunci
  • Iterate melalui entrySet() dan untuk menemukan kunci yang sesuai dengan nilai. Ini adalah yang paling lambat metode, karena memerlukan iterasi melalui seluruh koleksi, sementara dua lainnya metode don't membutuhkan itu.
Komentar (1)

Anda bisa menyisipkan kedua kunci,nilai pasangan dan terbalik ke dalam peta struktur

map.put("theKey", "theValue");
map.put("theValue", "theKey");

Menggunakan peta.mendapatkan("nilai") kemudian akan kembali "theKey".

It's cepat dan kotor cara yang saya've dibuat konstan maps, yang hanya akan bekerja untuk beberapa pilih dataset:

  • Berisi hanya 1 untuk 1 pasang
  • Set nilai-nilai adalah disjoint dari set tombol (1->2, 2->3 istirahat itu)
Komentar (1)

Menghias peta dengan implementasi sendiri

class MyMap extends HashMap{

    Map reverseMap = new HashMap();

    @Override
    public V put(K key, V value) {
        // TODO Auto-generated method stub
        reverseMap.put(value, key);
        return super.put(key, value);
    }

    public K getKey(V value){
        return reverseMap.get(value);
    }
}
Komentar (1)

Untuk menemukan semua tombol yang memetakan nilai tersebut, iterate melalui semua pasangan dalam hashmap, menggunakan peta.entrySet().

Komentar (1)

Tidak ada jawaban jelas, karena beberapa tombol yang dapat peta untuk nilai yang sama. Jika anda adalah menegakkan unik-ness dengan kode anda sendiri, solusi terbaik adalah untuk menciptakan sebuah kelas yang menggunakan dua Hashmaps untuk melacak pemetaan di kedua arah.

Komentar (0)

Jika anda membangun peta dalam kode anda sendiri, cobalah menempatkan kunci dan nilai di peta bersama-sama:

public class KeyValue {
    public Object key;
    public Object value;
    public KeyValue(Object key, Object value) { ... }
}

map.put(key, new KeyValue(key, value));

Kemudian ketika anda memiliki nilai, anda juga memiliki kunci.

Komentar (2)

Saya pikir ini adalah solusi terbaik, asli alamat: Java2s

    import java.util.HashMap;
    import java.util.Map;

        public class Main {

          public static void main(String[] argv) {
            Map map = new HashMap();
            map.put("1","one");
            map.put("2","two");
            map.put("3","three");
            map.put("4","four");

            System.out.println(getKeyFromValue(map,"three"));
          }

// hm is the map you are trying to get value from it
          public static Object getKeyFromValue(Map hm, Object value) {
            for (Object o : hm.keySet()) {
              if (hm.get(o).equals(value)) {
                return o;
              }
            }
            return null;
          }
        }

Penggunaan yang mudah: jika anda menempatkan semua data di hasMap dan anda memiliki item = "Mobil", sehingga anda yang mencari kunci dalam hashMap. itu adalah solusi yang baik.

getKeyFromValue(hashMap, item);
System.out.println("getKeyFromValue(hashMap, item): "+getKeyFromValue(hashMap, item));
Komentar (0)

Menggunakan Java 8:

ftw.forEach((key, value) -> {
    if (value.equals("foo")) {
        System.out.print(key);
    }
});
Komentar (2)

Kedengarannya seperti cara terbaik bagi anda untuk iterate atas entri menggunakan peta.entrySet() sejak peta.containsValue() mungkin hal ini pula.

Komentar (2)

I'm takut anda'll hanya untuk iterate peta anda. Singkat saya bisa datang dengan:

Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
    Map.Entry entry = iter.next();
    if (entry.getValue().equals(value_you_look_for)) {
        String key_you_look_for = entry.getKey();
    }
}
Komentar (0)
for(int key: hm.keySet()) {
    if(hm.get(key).equals(value)) {
        System.out.println(key); 
    }
}
Komentar (0)

Untuk pengembangan Android menargetkan API < 19, Vitalii Fedorenko satu-ke-satu hubungan solusi doesn't bekerja karena benda-Benda.sama dengan isn't dilaksanakan. Berikut ini's sederhana alternatif:

public  K getKeyByValue(Map map, V value) {
    for (Map.Entry entry : map.entrySet()) {
            if (value.equals(entry.getValue())) {
            return entry.getKey();
        }
    }
    return null;
}
Komentar (1)

Anda dapat menggunakan berikut:

public class HashmapKeyExist {
    public static void main(String[] args) {
        HashMap hmap = new HashMap();
        hmap.put("1", "Bala");
        hmap.put("2", "Test");

        Boolean cantain = hmap.containsValue("Bala");
        if(hmap.containsKey("2") && hmap.containsValue("Test"))
        {
            System.out.println("Yes");
        }
        if(cantain == true)
        {
            System.out.println("Yes"); 
        }

        Set setkeys = hmap.keySet();
        Iterator it = setkeys.iterator();

        while(it.hasNext())
        {
            String key = (String) it.next();
            if (hmap.get(key).equals("Bala"))
            {
                System.out.println(key);
            }
        }
    }
}
Komentar (1)

Di java8

map.entrySet().stream().filter(entry -> entry.getValue().equals(value))
    .forEach(entry -> System.out.println(entry.getKey()));
Komentar (0)

Ya, anda memiliki untuk loop melalui hashmap, kecuali jika anda menerapkan sesuatu di sepanjang baris dari apa berbagai jawaban sarankan. Daripada mengutak-atik entrySet, I'a hanya mendapatkan keySet(), iterate atas yang mengatur, dan menjaga (pertama) kunci yang akan anda mencocokkan nilai. Jika anda membutuhkan semua tombol yang sesuai dengan nilai tersebut, jelas anda harus melakukan semuanya.

Sebagai Jonas menunjukkan, ini mungkin sudah menjadi apa containsValue metode lakukan, sehingga anda mungkin hanya melewati tes itu semua bersama-sama, dan hanya melakukan iterasi setiap saat (atau mungkin compiler sudah akan menghilangkan redundansi, siapa yang tahu).

Juga, relatif terhadap jawaban yang lain, jika anda reverse peta terlihat seperti

Map

anda dapat bergerak dengan bebas-kunci unik->nilai pemetaan, jika anda membutuhkan kemampuan (menguraikan mereka ke samping). Yang akan menggabungkan baik menjadi salah satu solusi yang menyarankan orang-orang di sini menggunakan dua peta.

Komentar (0)

Anda bisa mendapatkan kunci dengan menggunakan nilai-nilai menggunakan kode berikut..

ArrayList valuesList = new ArrayList();
Set keySet = initalMap.keySet();
ArrayList keyList = new ArrayList(keySet);

for(int i = 0 ; i < keyList.size() ; i++ ) {
    valuesList.add(initalMap.get(keyList.get(i)));
}

Collections.sort(valuesList);
Map finalMap = new TreeMap();
for(int i = 0 ; i < valuesList.size() ; i++ ) {
    String value = (String) valuesList.get(i);

    for( int j = 0 ; j < keyList.size() ; j++ ) {
        if(initalMap.get(keyList.get(j)).equals(value)) {
            finalMap.put(keyList.get(j),value);
        }   
    }
}
System.out.println("fianl map ---------------------->  " + finalMap);
Komentar (0)
public static class SmartHashMap  {
    public HashMap keyValue;
    public HashMap valueKey;

    public SmartHashMap(){
        this.keyValue = new HashMap();
        this.valueKey = new HashMap();
    }

    public void add(T1 key, T2 value){
        this.keyValue.put(key, value);
        this.valueKey.put(value, key);
    }

    public T2 getValue(T1 key){
        return this.keyValue.get(key);
    }

    public T1 getKey(T2 value){
        return this.valueKey.get(value);
    }

}
Komentar (5)