source

Java 해시맵:가치에서 키를 얻는 방법

bestscript 2023. 2. 5. 09:40

Java 해시맵:가치에서 키를 얻는 방법

"foo"및 , , 및HashMap<String> ftw ftw.containsValue("foo")true대응하는 키를 입수하려면 어떻게 해야 합니까?시맵맵 루프 ?? ????것을하 하장 ??? ???

데이터 구조에 키와 값 간에 다대일 매핑이 있는 경우 엔트리에 대해 반복하고 적절한 키를 모두 선택해야 합니다.

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;
}

일대일 관계일 경우 처음 일치한 키를 반환할 수 있습니다.

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;
}

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());
}

또한 Guava 사용자에게는 BiMap이 유용할 수 있습니다.예를 들어 다음과 같습니다.

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

표준 Java Collections 프레임워크 대신 Commons Collections 라이브러리를 사용하는 경우 이를 쉽게 수행할 수 있습니다.

Collections 라이브러리의 인터페이스는 양방향 맵으로, 키를 값에 매핑할 수 있습니다(일반 맵과 같음).또한 값을 키에 매핑할 수 있기 때문에 양방향으로 룩업을 실행할 수 있습니다.이 방법에서는 값의 키를 취득할 수 있습니다.

단, 주의사항이 있습니다.bidi 맵은 키에 여러 값을 매핑할 수 없습니다.따라서 데이터 세트에 키와 값 간의 1:1 매핑이 없는 한 bidi 맵을 사용할 수 없습니다.


Java Collections API에 의존하려면 맵에 값을 삽입할 때 키와 값 사이의 1:1 관계를 확인해야 합니다.이것은 말하기는 쉽고 실행하기는 어렵다.

이를 확인할 수 있으면 메서드를 사용하여 맵의 엔트리(매핑) 세트를 가져옵니다.타입이 「」인 세트를 취득하면, 엔트리를 반복해 보존된 값과 예상한 값을 비교하고, 대응하는 키를 취득합니다.


범용 Bidi 맵에 대한 지원은 Google Guava 및 리팩터링된 Commons-Collections 라이브러리에서 찾을 수 있습니다(후자는 Apache 프로젝트가 아닙니다).Apache Commons Collections에서 범용 지원이 누락되었음을 지적해 주셔서 감사합니다.제네릭과 함께 컬렉션을 사용하면 유지보수가 용이한 코드를 만들 수 있습니다.


버전 4.0 이후 Apache Commons Collections™ 공식 라이브러리는 제네릭을 지원합니다.

"org.apache.commons.collections4" 요약 페이지를 참조하십시오.bidimap" 패키지는 사용 가능한 구현 목록 및 현재 Java 제네릭을 지원하는 인터페이스입니다.

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());
            }
        }
    }
}

추가 정보...도움이 될 수 있습니다.

해시맵이 너무 크면 위의 방법이 좋지 않을 수 있습니다.해시맵에 고유 키와 고유 값 매핑이 포함되어 있는 경우 값에서 키로의 매핑을 포함하는 해시맵을 하나 더 유지할 수 있습니다.

즉, 2개의 해시맵을 유지해야 합니다.

1. Key to value

2. Value to key 

이 경우 두 번째 해시맵을 사용하여 키를 가져올 수 있습니다.

키, 값 쌍 및 그 역수를 지도 구조에 모두 삽입할 수 있습니다.

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

map.get("the Value")를 사용하면 "the Key"가 반환됩니다.

이렇게 하면 일부 데이터셋에서만 사용할 수 있는 지속적인 맵을 빠르고 간편하게 만들 수 있습니다.

  • 1쌍부터 1쌍만 포함됩니다.
  • 값 집합이 키 집합에서 분리됨(1->2, 2->3으로 분리됨)

당신의 선택은

  • 구글 컬렉션의 BiMap과 같이 이를 위해 만들어진 지도 구현을 사용합니다.구글 컬렉션 BiMap은 키뿐만 아니라 값도 고유해야 하지만 양방향에서 높은 성능을 제공합니다.
  • 수동으로 2개의 맵을 유지 보수합니다.하나는 키 > 값 맵, 다른 하나는 값 맵 > 키
  • 말을 entrySet()이치노이 방법은 전체 컬렉션에 걸쳐 반복해야 하지만 다른 두 가지 방법에는 반복할 필요가 없기 때문에 가장 느린 방법입니다.

Java 8 사용:

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

독자적인 구현으로 맵을 꾸미다

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);
    }
}

여러 키가 같은 값에 매핑될 수 있기 때문에 명확한 답은 없습니다.독자적인 코드로 일의성을 적용하는 경우는, 2개의 해시 맵을 사용해 쌍방향의 매핑을 추적하는 클래스를 작성하는 것이 최선의 해결책입니다.

독자적인 코드로 맵을 작성하는 경우는, 맵내의 키와 값을 함께 입력해 주세요.

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

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

그리고 값이 있으면 키도 있습니다.

이것이 최선의 솔루션이라고 생각합니다.원래 주소: 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;
          }
        }

쉬운 사용법: 모든 데이터를 hasMap에 넣고 항목 = "자동"을 가지고 있다면 hashMap에서 키를 찾을 수 있습니다. 좋은 솔루션입니다.

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

값에 내의 을 반복하여 합니다.map.entrySet().

죄송하지만 지도를 다시 한 번 읽어 보세요.내가 생각해낼 수 있는 가장 짧은 방법:

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();
    }
}
for(int key: hm.keySet()) {
    if(hm.get(key).equals(value)) {
        System.out.println(key); 
    }
}

'아까보다'를 사용해서 것이 인 것 요.map.entrySet()부터map.containsValue()아마 이렇게 할 거야

API < 19를 대상으로 한 Android 개발에서는 Vitalii Fedorenko 일대일 관계 솔루션이 작동하지 않습니다.Objects.equals구현되지 않았습니다.간단한 대안은 다음과 같습니다.

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;
}

다음을 사용할 수 있습니다.

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);
            }
        }
    }
}

keySet()이 값에 매핑된 키를 찾아 entrySet()보다 더 나은 코딩 스타일을 가질 수 있다고 생각합니다.

예:

HashMap 맵, ArrayList res, 에 대한 모든 키 매핑을 검색하여 Res에 키를 저장한다고 가정합니다.

아래에 코드를 쓸 수 있습니다.

    for (int key : map.keySet()) {
        if (map.get(key) == value) {
            res.add(key);
        }
    }

다음 entrySet()을 사용하는 대신:

    for (Map.Entry s : map.entrySet()) {
        if ((int)s.getValue() == value) {
            res.add((int)s.getKey());
        }
    }

도움이 되었으면 좋겠다:)

네, 이러한 다양한 답변에 따라 무언가를 구현하지 않는 한 해시맵을 루프해야 합니다.entrySet을 만지작거리는 대신 keySet()을 가져와 해당 세트에 대해 반복하고 일치하는 값을 얻을 수 있는 (첫 번째) 키를 유지합니다.이 값에 일치하는 키가 모두 필요한 경우 모든 작업을 수행해야 합니다.

Jonas가 제안했듯이, 이것이 이미 containsValue 메서드가 하고 있는 것일 수 있으므로, 테스트를 모두 건너뛰고 매번 반복할 수도 있습니다(혹은 컴파일러가 이미 중복성을 제거할 수도 있습니다).

또한 다른 답변과 비교하여 역방향 맵이 다음과 같은 경우

Map<Value, Set<Key>>

이 기능이 필요한 경우(해제할 수 없는) 비메모리 키>값 매핑을 처리할 수 있습니다.두 개의 지도를 사용하여 사람들이 제안하는 어떤 해결책에도 벌금을 부과할 수 있습니다.

다음 코드를 사용하여 값을 사용하여 키를 얻을 수 있습니다.

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);
    }

}

Java8의 경우

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

얇은 래퍼 사용: HMap

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

public class HMap<K, V> {

   private final Map<K, Map<K, V>> map;

   public HMap() {
      map = new HashMap<K, Map<K, V>>();
   }

   public HMap(final int initialCapacity) {
      map = new HashMap<K, Map<K, V>>(initialCapacity);
   }

   public boolean containsKey(final Object key) {
      return map.containsKey(key);
   }

   public V get(final Object key) {
      final Map<K, V> entry = map.get(key);
      if (entry != null)
         return entry.values().iterator().next();
      return null;
   }

   public K getKey(final Object key) {
      final Map<K, V> entry = map.get(key);
      if (entry != null)
         return entry.keySet().iterator().next();
      return null;
   }

   public V put(final K key, final V value) {
      final Map<K, V> entry = map
            .put(key, Collections.singletonMap(key, value));
      if (entry != null)
         return entry.values().iterator().next();
      return null;
   }
}
public static String getKey(Map<String, Integer> mapref, String value) {
    String key = "";
    for (Map.Entry<String, Integer> map : mapref.entrySet()) {
        if (map.getValue().toString().equals(value)) {
            key = map.getKey();
        }
    }
    return key;
}
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class ValueKeysMap<K, V> extends HashMap <K,V>{
    HashMap<V, Set<K>> ValueKeysMap = new HashMap<V, Set<K>>();

    @Override
    public boolean containsValue(Object value) {
        return ValueKeysMap.containsKey(value);
    }

    @Override
    public V put(K key, V value) {
        if (containsValue(value)) {
            Set<K> keys = ValueKeysMap.get(value);
            keys.add(key);
        } else {
            Set<K> keys = new HashSet<K>();
            keys.add(key);
            ValueKeysMap.put(value, keys);
        }
        return super.put(key, value);
    }

    @Override
    public V remove(Object key) {
        V value = super.remove(key);
        Set<K> keys = ValueKeysMap.get(value);
        keys.remove(key);
        if(keys.size() == 0) {
           ValueKeysMap.remove(value);
        }
        return value;
    }

    public Set<K> getKeys4ThisValue(V value){
        Set<K> keys = ValueKeysMap.get(value);
        return keys;
    }

    public boolean valueContainsThisKey(K key, V value){
        if (containsValue(value)) {
            Set<K> keys = ValueKeysMap.get(value);
            return keys.contains(key);
        }
        return false;
    }

    /*
     * Take care of argument constructor and other api's like putAll
     */
}
/**
 * This method gets the Key for the given Value
 * @param paramName
 * @return
 */
private String getKeyForValueFromMap(String paramName) {
    String keyForValue = null;
    if(paramName!=null)) {
        Set<Entry<String,String>> entrySet = myMap().entrySet();
        if(entrySet!=null && entrySet.size>0) {
            for(Entry<String,String> entry : entrySet) {
                if(entry!=null && paramName.equalsIgnoreCase(entry.getValue())) {
                    keyForValue = entry.getKey();
                }
            }
        }
    }
    return keyForValue;
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class M{
public static void main(String[] args) {

        HashMap<String, List<String>> resultHashMap = new HashMap<String, List<String>>();

        Set<String> newKeyList = resultHashMap.keySet();


        for (Iterator<String> iterator = originalHashMap.keySet().iterator(); iterator.hasNext();) {
            String hashKey = (String) iterator.next();

            if (!newKeyList.contains(originalHashMap.get(hashKey))) {
                List<String> loArrayList = new ArrayList<String>();
                loArrayList.add(hashKey);
                resultHashMap.put(originalHashMap.get(hashKey), loArrayList);
            } else {
                List<String> loArrayList = resultHashMap.get(originalHashMap
                        .get(hashKey));
                loArrayList.add(hashKey);
                resultHashMap.put(originalHashMap.get(hashKey), loArrayList);
            }
        }

        System.out.println("Original HashMap : " + originalHashMap);
        System.out.println("Result HashMap : " + resultHashMap);
    }
}

내 2센트.어레이에서 키를 가져온 후 어레이를 루프할 수 있습니다.맵이 꽤 큰 경우, 이 코드 블록의 퍼포먼스에 영향을 줍니다.이 경우, 우선 어레이내의 키를 취득해, 그 후에 루프를 실시할 가능성이 있습니다.그렇지 않으면 크기가 작은 지도에서는 문제가 없습니다.

String[] keys =  yourMap.keySet().toArray(new String[0]);

for(int i = 0 ; i < keys.length ; i++){
    //This is your key    
    String key = keys[i];

    //This is your value
    yourMap.get(key)            
}

이것이 질문에 직접 답하는 것은 아니지만 관련이 있습니다.

이렇게 하면 계속 작성/반복할 필요가 없습니다.역지도를 한 번만 작성하면 원하는 것을 얻을 수 있습니다.

/**
 * Both key and value types must define equals() and hashCode() for this to work.
 * This takes into account that all keys are unique but all values may not be.
 *
 * @param map
 * @param <K>
 * @param <V>
 * @return
 */
public static <K, V> Map<V, List<K>> reverseMap(Map<K,V> map) {
    if(map == null) return null;

    Map<V, List<K>> reverseMap = new ArrayMap<>();

    for(Map.Entry<K,V> entry : map.entrySet()) {
        appendValueToMapList(reverseMap, entry.getValue(), entry.getKey());
    }

    return reverseMap;
}


/**
 * Takes into account that the list may already have values.
 * 
 * @param map
 * @param key
 * @param value
 * @param <K>
 * @param <V>
 * @return
 */
public static <K, V> Map<K, List<V>> appendValueToMapList(Map<K, List<V>> map, K key, V value) {
    if(map == null || key == null || value == null) return map;

    List<V> list = map.get(key);

    if(list == null) {
        List<V> newList = new ArrayList<>();
        newList.add(value);
        map.put(key, newList);
    }
    else {
        list.add(value);
    }

    return map;
}

Map에서 지정된 값의 키를 가져오는 가장 간단한 유틸리티 방법:

public static void fetchValue(Map<String, Integer> map, Integer i)
{   
Stream stream = map.entrySet().stream().filter(val-> val.getValue().equals(i)).map(Map.Entry::getKey);
stream.forEach(System.out::println);    
}

자세한 설명:

  1. Method fetchValue는 String을 키로, Integer를 값으로 하는 맵을 받아들입니다.

  2. 그런 다음 entryset().stream()을 사용하여 결과를 스트림으로 변환합니다.

  3. 다음으로 필터(중간 연산)를 사용하여 두 번째 인수와 동일한 값을 제공합니다.

  4. 마지막으로 각(최종 작업)에 대해 최종 결과를 인쇄합니다.

너무 많은 답을 찾았습니다.몇몇은 정말 훌륭했다.하지만 저는 특히 루프를 이용해 가치를 얻을 수 있는 방법을 찾고 있었습니다.

마지막으로 HashMap 1 대 1 관계에 대해 다음 작업을 수행했습니다.

    Map<String, String> map = new HashMap<String, String>();
    
    map.put("abc", "123");
    map.put("xyz", "456");
    
    for(Entry<String, String> entry : map.entrySet()) {
        if(entry.getValue().equalsIgnoreCase("456")) {
            System.out.println(entry.getKey());
        }
    }

출력: "xyz"

HashMap 1 대 다 관계의 경우:

    Map<String, ArrayList<String>> service = new HashMap<String, ArrayList<String>>();
    
    service.put("abc", new ArrayList<String>());
    service.get("abc").add("a");
    service.get("abc").add("b");
    service.get("abc").add("c");
    
    service.put("xyz", new ArrayList<String>());
    service.get("xyz").add("x");
    service.get("xyz").add("y");
    service.get("xyz").add("z");
    
    for(Entry<String, ArrayList<String>> entry : service.entrySet()) {
        ArrayList<String> values = entry.getValue();
        for(String value : values) {
            if(value.equalsIgnoreCase("x")) {
                System.out.println(entry.getKey());
            }
        }
        
    }

출력: xyz

-감사합니다. -감사합니다.

언급URL : https://stackoverflow.com/questions/1383797/java-hashmap-how-to-get-key-from-value