Dacă aș avea valoarea "foo"
, și un HashMappentru care
ftw.containsValue("foo")` returnează "adevărat", cum pot obține tasta corespunzătoare? Trebuie să-bucla prin hashmap? Ceea ce este cel mai bun mod de a face asta?
Dacă structura de date a mulți-la-unu mapare între chei și valori ar trebui să itera peste intrările și ridica toate chei potrivite:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
Set<T> keys = new HashSet<T>();
for (Entry<T, E> entry : map.entrySet()) {
if (Objects.equals(value, entry.getValue())) {
keys.add(entry.getKey());
}
}
return keys;
}
În caz de unu-la-unu relație, puteți reveni la prima cheie potrivite:
public static <T, E> T getKeyByValue(Map<T, E> map, E value) {
for (Entry<T, E> entry : map.entrySet()) {
if (Objects.equals(value, entry.getValue())) {
return entry.getKey();
}
}
return null;
}
În Java 8:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
return map.entrySet()
.stream()
.filter(entry -> Objects.equals(entry.getValue(), value))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
De asemenea, pentru Guava utilizatori, BiMap poate fi util. De exemplu:
BiMap<Token, Character> tokenToChar =
ImmutableBiMap.of(Token.LEFT_BRACKET, '[', Token.LEFT_PARENTHESIS, '(');
Token token = tokenToChar.inverse().get('(');
Character c = tokenToChar.get(token);
Dacă alegeți să utilizați Commons Colecții de bibliotecă în loc de standard de Colecții Java API, puteți realiza acest lucru cu ușurință.
De BidiMap interfață în Colecțiile bibliotecii este un bi-directional hartă, permițându-vă pentru a mapa o cheie pentru o valoare (cum ar fi hărți normale), și, de asemenea, pentru a mapa o valoare pentru o cheie, astfel permițându-vă pentru a efectua căutări în ambele direcții. Obține o cheie pentru o valoare este susținută de getKey() metoda.
Există un avertisment, deși, bidi hărți nu poate avea mai multe valori mapate la chei, și, prin urmare, cu excepția cazului în setul de date are 1:1 mapările între chei și valori, nu puteți utiliza bidimaps.
Update
Dacă doriți să se bazeze pe Colecții Java API, va trebui să se asigure relația 1:1 între chei și valori la momentul de a introduce valoarea în hartă. Acest lucru este mai ușor de zis decât de făcut.
Odată ce vă pot asigura că, folosi entrySet() metoda pentru a obține un set de intrări (operatori), în Hartă. După ce ați obținut setul al căror tip este Hartă.Intrarea, repeta prin intrări, comparând stocate valoare împotriva așteptat, și de a obține tasta.
Update #2
Suport pentru bidi hărți cu generice pot fi găsite în Google Guava și refactored Commons-Colectii biblioteci (acesta din urmă nu este un Apache proiect). Datorită Esko pentru arătând lipsă generic sprijin în Apache Commons Colecții. Folosind colecții cu generice face mai mult cod de întreținut.
public class NewClass1 {
public static void main(String[] args) {
Map<Integer, String> testMap = new HashMap<Integer, String>();
testMap.put(10, "a");
testMap.put(20, "b");
testMap.put(30, "c");
testMap.put(40, "d");
for (Entry<Integer, String> entry : testMap.entrySet()) {
if (entry.getValue().equals("c")) {
System.out.println(entry.getKey());
}
}
}
}
Unele informații suplimentare... Pot fi utile pentru tine
Metoda de mai sus nu poate fi bun dacă hashmap este foarte mare. Dacă hashmap conțin cheie unică valoare unică de cartografiere, vă puteți menține o mai hashmap care conțin cartografiere de Valoare-Cheie.
Asta este, va trebui să mențină două hashmaps
1. Key to value
2. Value to key
În acest caz, puteți folosi de-al doilea hashmap pentru a obține cheia.
Cred că alegerile tale sunt
entrySet()
și pentru a găsi cheile care se potrivesc valoare. Aceasta este cea mai lentă metodă, deoarece necesită iterarea prin întreaga colecție, în timp ce celelalte două metode nu't nevoie de asta.Ai putea introduce cheia,valoarea pereche și invers în structura hartă
map.put("theKey", "theValue");
map.put("theValue", "theKey");
Folosind harta.ia("valoarea") va reveni apoi "theKey".
L's-o rapid și murdar modul în care am'am făcut constant maps, care va funcționa doar pentru câteva selectați seturi de date:
Decora harta cu propria implementare
class MyMap<K,V> extends HashMap<K, V>{
Map<V,K> reverseMap = new HashMap<V,K>();
@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);
}
}
Nu există nici un răspuns fără echivoc, pentru că mai multe chei harta la aceeași valoare. Dacă sunteți aplicarea unic-ness cu propriul cod, cea mai bună soluție este de a crea o clasă care utilizează două Hashmaps pentru a urmări operatori în ambele direcții.
Dacă vă construi harta în propriul cod, încercați să puneți cheia și valoarea de pe hartă, împreună:
public class KeyValue {
public Object key;
public Object value;
public KeyValue(Object key, Object value) { ... }
}
map.put(key, new KeyValue(key, value));
Atunci când ai o valoare, aveți, de asemenea, cheia.
Cred că aceasta este cea mai bună soluție, adresa original: Java2s
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] argv) {
Map<String, String> map = new HashMap<String, String>();
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;
}
}
O utilizare mai usoara: dacă ai pus toate datele în hasMap și trebuie element = "Auto", deci, sunteți în căutarea sale cheie în hashMap. că este o soluție bună.
getKeyFromValue(hashMap, item);
System.out.println("getKeyFromValue(hashMap, item): "+getKeyFromValue(hashMap, item));
Am'm teamă că'll trebuie doar pentru a repeta hartă. Mai scurt am putut veni cu:
Iterator<Map.Entry<String,String>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String,String> entry = iter.next();
if (entry.getValue().equals(value_you_look_for)) {
String key_you_look_for = entry.getKey();
}
}
Pentru Android de dezvoltare vizează API < 19, Vitalii Fedorenko unu-la-unu relație soluție nu't de lucru pentru Obiecte.este egal cu` e't puse în aplicare. Aici's o alternativă simplă:
public <K, V> K getKeyByValue(Map<K, V> map, V value) {
for (Map.Entry<K, V> entry : map.entrySet()) {
if (value.equals(entry.getValue())) {
return entry.getKey();
}
}
return null;
}
Puteți utiliza de mai jos:
public class HashmapKeyExist {
public static void main(String[] args) {
HashMap<String, String> hmap = new HashMap<String, String>();
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);
}
}
}
}
Da, trebuie sa bucla prin hashmap, dacă nu pune în aplicare ceva de-a lungul liniilor de ce aceste diverse răspunsuri sugerează. Mai degrabă decât se ține de fleacuri cu entrySet, am'd obține doar keySet(), repeta peste care a stabilit și menține (în primul rând) pentru că devine potrivire valoare. Dacă aveți nevoie de toate cheile care se potrivesc cu acea valoare, evident, tu trebuie să faci toată treaba.
Ca Jonas sugerează, acest lucru ar putea fi deja ce containsValue metodă este de a face, așa că ai putea să treci testul de tot, și doar nu repetare în fiecare moment (sau poate compilatorul va elimina redundanța, cine știe).
De asemenea, în raport cu alte răspunsuri, dacă inversă arată hartă
Map<Value, Set<Key>>
puteți face cu non-cheie unică->valoarea operatori, dacă aveți nevoie de această capacitate (untangling-le deoparte). Care să încorporeze bine în oricare dintre soluții oameni sugerează aici cu ajutorul a două hărți.
Puteți obține cheia folosind valorile folosind următorul cod..
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);
public static class SmartHashMap <T1 extends Object, T2 extends Object> {
public HashMap<T1, T2> keyValue;
public HashMap<T2, T1> valueKey;
public SmartHashMap(){
this.keyValue = new HashMap<T1, T2>();
this.valueKey = new HashMap<T2, T1>();
}
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);
}
}