값 "foo"
이 있고 HashMap<String> ftw
를 ftw.containsValue("foo")
반환 true
하는 경우 해당 키를 어떻게 얻을 수 있습니까? 해시 맵을 반복해야합니까? 가장 좋은 방법은 무엇입니까?
답변
표준 Java Collections API 대신 Commons Collections 라이브러리 를 사용하도록 선택하면 이를 쉽게 달성 할 수 있습니다.
Collections 라이브러리 의 BidiMap 인터페이스는 양방향 맵이므로 키를 값 (예 : 일반 맵)에 맵핑하고 값을 키에 맵핑 할 수 있으므로 양방향으로 조회를 수행 할 수 있습니다. getKey () 메소드 는 값에 대한 키를 얻는 것을 지원합니다 .
그러나 bidi 맵에는 여러 값을 키에 매핑 할 수 없으므로 데이터 세트에 키와 값 사이에 1 : 1 매핑이 없으면 입찰을 사용할 수 없습니다.
최신 정보
Java Collections API를 사용하려면 값을 맵에 삽입 할 때 키와 값 사이의 1 : 1 관계를 보장해야합니다. 이것은 말보다 쉽습니다.
확인 후 entrySet () 메소드 를 사용하여 맵에서 항목 세트 (매핑)를 얻습니다. 유형이 Map.Entry 인 세트를 얻은 후에 는 저장된 값 을 예상 과 비교하여 항목을 반복 하고 해당 키를 얻습니다 .
업데이트 # 2
제네릭을 사용한 bidi 맵 지원은 Google Guava 및 리팩토링 된 Commons-Collections 라이브러리 에서 찾을 수 있습니다 (후자는 Apache 프로젝트가 아닙니다). Apache Commons Collections에서 누락 된 일반 지원을 지적한 Esko에게 감사합니다. 제네릭과 함께 컬렉션을 사용하면 유지 관리하기 쉬운 코드가 만들어집니다.
답변
데이터 구조 에 키와 값 사이의 다 대일 매핑이있는 경우 항목을 반복하고 적합한 키를 모두 선택해야합니다.
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;
}
자바 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());
}
또한 구아바 사용자의 경우 BiMap 이 유용 할 수 있습니다. 예를 들면 다음과 같습니다.
BiMap<Token, Character> tokenToChar =
ImmutableBiMap.of(Token.LEFT_BRACKET, '[', Token.LEFT_PARENTHESIS, '(');
Token token = tokenToChar.inverse().get('(');
Character c = tokenToChar.get(token);
답변
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());
}
}
}
}
추가 정보 … 도움이 될 수 있습니다
해시 맵이 실제로 큰 경우 위의 방법이 좋지 않을 수 있습니다. 해시 맵에 고유 키 대 고유 값 맵핑이 포함 된 경우 값에서 키로의 맵핑을 포함하는 하나 이상의 해시 맵을 유지할 수 있습니다.
즉, 두 개의 해시 맵을 유지해야합니다
1. Key to value
2. Value to key
이 경우 두 번째 해시 맵을 사용하여 키를 얻을 수 있습니다.
답변
당신의 선택은
- Google 컬렉션 의 BiMap 과 같이이를 위해 빌드 된 맵 구현을 사용하십시오 . Google 컬렉션 BiMap에는 키뿐만 아니라 고유 한 값이 필요하지만 양방향 성능에서 높은 성능을 제공합니다.
- 키-> 값에 대한 맵과 값-> 키에 대한 맵을 수동으로 유지 관리
- 및를 반복
entrySet()
하여 값과 일치하는 키를 찾습니다. 이 방법은 전체 컬렉션을 반복해야하는 반면 다른 두 방법은 필요하지 않기 때문에 가장 느린 방법입니다.
답변
키, 값 쌍 및 그 역수를 모두 맵 구조에 삽입 할 수 있습니다.
map.put("theKey", "theValue");
map.put("theValue", "theKey");
map.get ( “theValue”)를 사용하면 “theKey”가 반환됩니다.
상수 맵을 만든 빠르고 더러운 방법입니다. 일부 맵 세트에서만 작동합니다.
- 1 ~ 1 쌍만 포함
- 값 세트가 키 세트와 분리되어 있습니다 (1-> 2, 2-> 3이 키를 분리).
답변
자신의 구현으로 맵을 장식하십시오.
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);
}
}
답변
여러 키가 동일한 값에 매핑 될 수 있으므로 명확한 대답은 없습니다. 자신의 코드로 고유성을 강화하는 경우 가장 좋은 해결책은 두 개의 해시 맵을 사용하여 양방향으로 매핑을 추적하는 클래스를 만드는 것입니다.