중복 키를 해시맵에 넣으면 어떻게 되는가?
동일한 키를 여러 번 전달하는 경우HashMap
의put
방법, 원래의 가치는 어떻게 되는가?그리고 만약 그 값마저 반복된다면?나는 이것에 대한 어떤 문서도 찾지 못했다.
사례 1: 키에 대한 덮어쓰기 값
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
System.out.println(mymap.get("1"));
우리는 얻는다.surely not one
.
사례 2: 중복 값
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
// The following line was added:
mymap.put("1","one");
System.out.println(mymap.get("1"));
우리는 얻는다.one
.
그러나 다른 가치들은 어떻게 되는가?나는 한 학생에게 기본을 가르치고 있었는데 이런 질문을 받았다.이다Map
(그러나 메모리에서) 마지막 값이 참조되는 버킷처럼?
정의에 따르면put
명령은 지도에서 지정된 키와 관련된 이전 값을 대체한다(일반적으로 원시 유형의 어레이 인덱싱 작업과 유사함).
그 지도는 단순히 그 가치에 대한 참조를 떨어뜨린다.다른 어떤 것도 객체에 대한 참조를 가지고 있지 않을 경우, 해당 객체는 가비지 수집의 대상이 된다.또한 Java는 지정된 키와 관련된 이전 값을 반환한다(또는null
존재하지 않는 경우), 즉 무엇이 존재했는지 확인하고 필요한 경우 참조를 유지하십시오.
자세한 내용은 다음을 참조하십시오.해시맵 문서
당신은 당신의 대답을 Map#put(K, V)의 자바도크에서 찾을 수 있을 것이다(실제로 무언가를 반환한다).
public V put(K key, V value)
지만장자 지만장자 지만장자 지만장자 키결(地지長子작업) 에 이 된다.이전에 지도에 이 키에 대한 매핑이 포함되어 있었다면 이전 값은 지정된 값으로 대체된다.(지도)
m
키에 대한 매핑이 포함되어 있다고 한다.k
돌아올 수만 있다면true
.)매개 변수:
key
지만(知) 을(를) 키.
value
되어야 할 값 - 지만 키와 값.반환:
된 키 지만 키와 값null
에 대한 매핑이 없다면key
. (A)null
반환은 또한 이전에 연결된 지도를 나타낼 수 있다.null
규정된 바와 같이key
, 구현이 지원하는 경우null
값).
전화할 때 반환된 값을 할당하지 않으면mymap.put("1", "a string")
그것은 단지 참조되지 않아 쓰레기 수거에 적합하게 된다.
기능이며 할 때 키/값 기능 중 하나를 얻을 수 없기 수 .
당신의 예에서 당신이 "1"의 가치를 얻고 싶을 때 그것은 어떤 것인가?
그것이 모든 값에 대해 고유한 키를 가지려는 이유지만 당신은 Java 표준 lib에 의한 트릭을 가질 수 있다.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class DuplicateMap<K, V> {
private Map<K, ArrayList<V>> m = new HashMap<>();
public void put(K k, V v) {
if (m.containsKey(k)) {
m.get(k).add(v);
} else {
ArrayList<V> arr = new ArrayList<>();
arr.add(v);
m.put(k, arr);
}
}
public ArrayList<V> get(K k) {
return m.get(k);
}
public V get(K k, int index) {
return m.get(k).size()-1 < index ? null : m.get(k).get(index);
}
}
그리고 당신은 이것을 다음과 같은 방법으로 사용할 수 있는 방법은 다음과 같다.
public static void main(String[] args) {
DuplicateMap<String,String> dm=new DuplicateMap<>();
dm.put("1", "one");
dm.put("1", "not one");
dm.put("1", "surely not one");
System.out.println(dm.get("1"));
System.out.println(dm.get("1",1));
System.out.println(dm.get("1", 5));
}
인쇄물의 결과는 다음과 같다.
[one, not one, surely not one]
not one
null
각각의 키에 대한 지도상의 기존 값을 대체한다.그리고 동일한 이름을 가진 키가 존재하지 않으면 제공된 값을 가진 키를 생성한다.예:
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","two");
OUTPUT 키 = "1", 값 = "2"
그래서 이전 값을 덮어쓰게 된다.
키의 이전 값은 삭제되고 새 값으로 대체된다.
키가 부여된 모든 값을 유지하려면 다음과 같은 기능을 구현해 보십시오.
import org.apache.commons.collections.MultiHashMap;
import java.util.Set;
import java.util.Map;
import java.util.Iterator;
import java.util.List;
public class MultiMapExample {
public static void main(String[] args) {
MultiHashMap mp=new MultiHashMap();
mp.put("a", 10);
mp.put("a", 11);
mp.put("a", 12);
mp.put("b", 13);
mp.put("c", 14);
mp.put("e", 15);
List list = null;
Set set = mp.entrySet();
Iterator i = set.iterator();
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
list=(List)mp.get(me.getKey());
for(int j=0;j<list.size();j++)
{
System.out.println(me.getKey()+": value :"+list.get(j));
}
}
}
}
지정된 값을 이 맵의 지정된 키와 연결하십시오.이전에 지도에 키에 대한 매핑이 포함되어 있었다면 이전 값은 대체된다.
그 지도가 양동이와 같았는지 아닌지에 대한 당신의 질문에:
와 함께 하는 리스트 같다.name=value
짝을 이루다name
String이 될 필요는 없다(하지만, 할 수 있다).
요소를 얻으려면 키를 get()-method에 전달하여 지정된 객체를 반환하십시오.
그리고 해시맵은 get-method를 사용하여 객체를 검색하려는 경우 실제 객체를 당신이 제공한 것과 비교하지 않는다는 것을 의미하는데, 그것은 목록을 통해 반복해서 현재 요소와 함께 제공한 키를 비교해야 하기 때문이다.
이것은 비효율적일 것이다.대신, 당신의 객체가 무엇으로 구성되어 있든 간에, 그것은 두 객체로부터 소위 해시코드를 계산하고 그것들을 비교한다.두 개를 비교하는 것이 더 쉽다.int
두 s의 의의 전체(매우) 물체 대.해시코드는 미리 정의된 길이(int)를 가진 요약과 같은 것으로 상상할 수 있으며, 따라서 고유하지 않고 충돌이 있다.링크를 삽입한 문서에서 해시코드 규칙을 찾으십시오.
만약 당신이 이것에 대해 더 알고 싶다면, 당신은 javapractices.com과 technofundo.com의 기사를 보는 것이 좋을 것이다.
안부 전해요
JDK의 맵은 중복된 키에 데이터를 저장하기 위한 것이 아니다.
기껏해야 새로운 가치가 이전의 가치보다 우선할 것이다.
더 나쁜 시나리오는 예외(예: 스트림으로 수집하려고 할 때):
중복 항목 없음:
Stream.of("one").collect(Collectors.toMap(x -> x, x -> x))
좋아. 받게 될거야: 2달러 ==> {one=one}
중복된 스트림:
Stream.of("one", "not one", "surely not one").collect(Collectors.toMap(x -> 1, x -> x))
예외 java.lang.잘못된 상태예외:중복 키 1(하나의 값이 아닌 병합 시도됨) | 수집기.duplicateKeyException (Collectors.java:133) | at Collectors.lambda$uniqKeysMapAccumulator$1 (Collectors.java:180) | at ReduceOps$3ReducingSink.accept (ReduceOps.java:169) | at Spliterators$ArraySpliterator.forEachRemaining (Spliterators.java:948) | at AbstractPipeline.copy(AbstractPipeline) 안으로.Java:484) | 추상 파이프라인에서.wrapAndCopy(AbstractPipeline) 안으로.Java:474) | ReducedOps$ReduceOp.evaluateSequential (ReduceOps.java:913) | 추상파이프라인.evaluate (AbstractPipeline) |Java:234) | ReferencePipeline.collect (ReferencePipeline)에서.자바:578) | (#4:1)
중복된 키를 처리하려면 다른 패키지(예: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html)를 사용하십시오.
중복된 키를 다루는 다른 구현들이 많이 있다.웹에 필요한 항목(예: 중복된 쿠키 키, HTTP 헤더는 동일한 필드를 가질 수 있음...)
행운을 빈다! :)
항상 사용:
HashMap<String, ArrayList<String>> hashy = new HashMap<String, ArrayList<String>>();
하나의 식별 키에 여러 가지를 적용하려면
public void MultiHash(){
HashMap<String, ArrayList<String>> hashy = new HashMap<String, ArrayList<String>>();
String key = "Your key";
ArrayList<String> yourarraylist = hashy.get(key);
for(String valuessaved2key : yourarraylist){
System.out.println(valuessaved2key);
}
}
넌 항상 이런 일을 할 수 있고 미로를 만들 수 있어!
public void LOOK_AT_ALL_THESE_HASHMAPS(){
HashMap<String, HashMap<String, HashMap<String, HashMap<String, String>>>> theultimatehashmap = new HashMap <String, HashMap<String, HashMap<String, HashMap<String, String>>>>();
String ballsdeep_into_the_hashmap = theultimatehashmap.get("firststring").get("secondstring").get("thirdstring").get("forthstring");
}
BTW, 이 키가 없는 경우에만 put과 같은 의미론을 원할 경우.사용할 수 있다concurrentHashMap
와 함께putIfAbsent()
기능을 발휘하다다음 사항을 확인하십시오.
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html#put(K,%20V)
concurrentHashMap
처리량을 향상시키기 위해 "잠금 스트라이핑" 메커니즘을 사용하기 때문에 높은 성능으로 스레드가 안전하다.
그렇다, 이것은 값이 있는 모든 1개의 키가 마지막 추가된 값으로 덮어쓰기 된다는 것을 의미한다. 여기서 당신은 "확실히 1개는 아니다"를 추가하면 "분명히 1개는 아니다"만 표시된다.
루프로 표시하려고 해도 같은 키를 가진 하나의 키와 값만 표시된다.
HashMap<Emp, Emp> empHashMap = new HashMap<Emp, Emp>();
empHashMap.put(new Emp(1), new Emp(1));
empHashMap.put(new Emp(1), new Emp(1));
empHashMap.put(new Emp(1), new Emp());
empHashMap.put(new Emp(1), new Emp());
System.out.println(empHashMap.size());
}
}
class Emp{
public Emp(){
}
public Emp(int id){
this.id = id;
}
public int id;
@Override
public boolean equals(Object obj) {
return this.id == ((Emp)obj).id;
}
@Override
public int hashCode() {
return id;
}
}
OUTPUT : is 1
올바르게 재정의된 경우 해시 맵에서 중복 항목이 허용되지 않는다는 의미와 해시 코드() 메서드를 의미한다.
HashSet도 내부적으로 HashMap을 사용한다. 원본 문서를 참조하십시오.
public class HashSet{
public HashSet() {
map = new HashMap<>();
}
}
참조URL: https://stackoverflow.com/questions/1669885/what-happens-when-a-duplicate-key-is-put-into-a-hashmap
'IT이야기' 카테고리의 다른 글
C에서 함수를 호출하기 전의 파라미터 평가 순서 (0) | 2022.05.20 |
---|---|
SSE/AVX와 함께 FMA(Fused Multiple-Add) 지침을 사용하는 방법 (0) | 2022.05.20 |
제출의 필드를 비우십시오(ve-validated vue). (0) | 2022.05.20 |
자바에서 예외를 던지지 않고 스택 추적을 버리는 방법이 있는가? (0) | 2022.05.20 |
Java에서 반복적으로 파일 나열 (0) | 2022.05.20 |