亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java map中如何實現相同key保存多個value值

發布時間:2021-08-30 09:26:37 來源:億速云 閱讀:569 作者:小新 欄目:開發技術

這篇文章主要介紹了java map中如何實現相同key保存多個value值,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

map中相同的key保存多個value值

在java中,Map集合中只能保存一個相同的key,如果再添加相同的key,則之后添加的key的值會覆蓋之前key對應的值,Map中一個key只存在唯一的值。

如下代碼

package test; 
import org.junit.Test; 
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map; 
import static java.util.Objects.hash; 
public class HashMapTest {
 
    @Test
    public void test0() {
        String str1 = new String("key");
        String str2 = new String("key");
        System.out.println(str1 == str2);
 
        Map<String,String> map = new HashMap<String,String>();
        map.put(str1,"value1");
        map.put(str2,"value2");//會覆蓋之前的值,map長度為1
        /**
         * map比較鍵是否相同時是根據hashCode()和equals()兩個方法進行比較
         * 先比較hashCode()是否相等,再比較equals()是否相等(實際上就是比較對象是否相等),如果都相等則認定是同一個鍵
         */
 
        for(Map.Entry<String,String> entry:map.entrySet()){
            System.out.println(entry.getKey()+"  "+entry.getValue());
        }
        System.out.println("------->"+map.get("key"));
    }
控制臺輸出如下: 
 
    /**
     * 以上代碼可以看出普通的map集合相同的key只能保存一個value
     * 但是有一個特殊的map--->IdentityHashMap可以實現一個key保存多個value
     * 注意:此類并不是通用的Map實現!此類再實現Map接口的時候違反了Map的常規協定,Map的常規協議在
     * 比較對象強制使用了equals()方法,但此類設計僅用于其中需要引用相等性語義的情況
     * (IdentityhashMap類利用哈希表實現Map接口,比較鍵(和值)時使用引用相等性代替對象相等性,
     * 也就是說做key(value)比較的時候只比較兩個key是否引用同一個對象)
     */
    @Test
    public void test1(){
        String str1 = "key";
        String str2 = "key";
        System.out.println(str1 == str2);
        Map<String,String> map = new IdentityHashMap<>();
        map.put(str1,"value1");
        map.put(str2,"value2");
        for(Map.Entry<String,String> entry:map.entrySet()){
            System.out.println(entry.getKey()+"  "+entry.getValue());
        }
        System.out.println("containsKey---->"+map.get("key"));
        System.out.println("value---->"+map.get("key"));
    }
 控制臺輸出如下 
 
 /**
     * test1中的IdentityHashMap中的key為“key”還是只保存了一個值,以為“key”在內存中只存在一個對象,
     * 而str1與str2對對"key"字符串的引用是相等的,所以添加的時候就發生了覆蓋
     */
 
    @Test
    public void test2(){
        String str1 = new String("key");
        String str2 = new String("key");
        System.out.println(str1 == str2);
        Map<String, String> map = new IdentityHashMap<>();
        map.put(str1,"value1");
        map.put(str2,"value2");
        for(Map.Entry<String,String> entry:map.entrySet()){
            System.out.println(entry.getKey()+"  "+entry.getValue());
        }
        System.out.println("\"key\" containKey--->"+map.containsKey("key"));
        System.out.println("str1 containKey--->"+map.containsKey(str1));
        System.out.println("str2 containKey--->"+map.containsKey(str2));
        System.out.println("value--->"+map.get("key"));
        System.out.println("value--->"+map.get(str1));
        System.out.println("value--->"+map.get(str2));
    }
 控制臺輸出如下:
 
 /**
     * test2中str1,str2都在內存中指向不同的String對象,他們的哈希值是不同的,所以在identityHashMap中可以的比較
     * 中會認為不同的key,所以會存在相同的“key”值對應不同的value值
     */ 
 
    /**
     * 既然提到了map的key的比較,再說一下map中實現自定義類做key值時應該注意的一些細節,
     * 在HashMap中對于key的比較時通過兩步完成的
     *  第一步:計算對象的hash Code的值,比較是否相等
     *  第二步: 檢查對應的hash code對應位置的對象是否相等
     *  在第一步中會調用到對象中的hashCode()方法,第二步中會調用的對象中的equals()方法
     *
     *  所以想要實現自定義對象作為Map的key值,保證key值的唯一性,需要在子定義對象中重寫以上兩個方法,如以下對象:
     */
    private class CustomObject{
        private String value; 
        public CustomObject(String value){
            this.value = value;
        }
 
        public String getValue() {
            return value;
        }
 
        public void setValue(String value) {
            this.value = value;
        }
 
        /**
         * 省略自定義的一些屬性方法
         * ......
         */ 
 
        @Override
        public int hashCode() {
            if(value !=null){
                return super.hashCode()+hash(value);
            }else{
                return super.hashCode();
            }
        }
 
        @Override
        public boolean equals(Object obj) {
            if(this == obj){
                return true;
            }
            if(obj == null || getClass() != obj.getClass()){
                return false;
            }
            CustomObject object = (CustomObject) obj;
            if(this.value != null && this.value.equals(object.getValue())){
                return true;
            }
            if(this.value == null && object.value == null){
                return true;
            }
            return false;
        }
    } 
}

Map中相同的鍵Key不同的值Value實現原理

Map中相同的鍵Key對應不同的值Value通常出現在樹形結構的數據處理中,通常的實現方法有JDK提供的IdentityHashMap和Spring提供的MultiValueMap。

public static void main(String[] args) {
	Map<String, Object> identity = new IdentityHashMap<>();
	identity.put("A", "A");
	identity.put("A", "B");
	identity.put("A", "C");
	Map<String, Object> identityString = new IdentityHashMap<>();
	identityString.put(String.join("A", ""), "B");
	identityString.put("A", "A");
	identityString.put(new String("A"), "C");
	MultiValueMap<String, Object> linked = new LinkedMultiValueMap<>();
	linked.add("A", "A");
	linked.add("A", "B");
	linked.add("A", "C");
	for (String key : identity.keySet()) {
		System.out.println("identity:" + identity.get(key));
	}
	for (String key : identityString.keySet()) {
		System.out.println("identity string:" + identityString.get(key));
	}
	for (String key : linked.keySet()) {
		System.out.println("linked:" + linked.get(key));
	}
}

實現原理

  • JDK提供的IdentityHashMap其底層是根據Key的hash碼的不同+transient Object[] table來實現的;

  • Spring提供的LinkedMultiValueMap其底層是使用LinkedHashMap來實現的;

  • LinkedHashMap的底層是使用transient Entry<K, V> head和transient Entry<K, V> tail來實現的;

  • Entry是LinkedHashMap的內部類,其定義方式為:

static class Entry<K, V> extends HashMap.Node<K, V> { Entry<K, V> before; Entry<K, V> after; }

感謝你能夠認真閱讀完這篇文章,希望小編分享的“java map中如何實現相同key保存多個value值”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

阿鲁科尔沁旗| 山东| 磐石市| 武功县| 毕节市| 罗定市| 文登市| 浮山县| 龙胜| 旌德县| 石景山区| 黔西县| 马公市| 文登市| 澄城县| 达拉特旗| 驻马店市| 苍梧县| 萨嘎县| 花莲市| 开江县| 衡阳市| 东兴市| 利川市| 嘉善县| 启东市| 元氏县| 镇雄县| 韶关市| 胶南市| 黑龙江省| 莎车县| 普洱| 平原县| 隆林| 孟津县| 鹿泉市| 会同县| 乌拉特中旗| 怀柔区| 湖南省|