優(yōu)雅編程之這樣使用Map,你就“正?!绷耍ㄈ?/h2>

開心一笑

【不要對一個程序員說:你的代碼有bug
他的第一個反應(yīng)是:1.你的環(huán)境有問題吧;2.傻逼你會用嗎。如果你委婉的說:你這個程序和預(yù)期的有點(diǎn)不一樣,你看是不是我的使用方法有問題。他本能的會想:操,是不是出bug了!】

提出問題

項(xiàng)目中一些不為人知卻好用的集合map有哪些???

解決問題

這里寫圖片描述
1. 雙向map:DualHashBidiMap

DualHashBidiMap可以通過key找到value,也可以通過value找到key

@Test
public void testDualHashBidiMap(){
    //雙向map
    BidiMap bidiMap = new DualHashBidiMap();
    bidiMap.put("Ay", "Boy");
    bidiMap.put("Al", "Girl");
    System.out.println("Key-Value:Ay = " + bidiMap.get("Ay"));//Key-Value:Ay = Boy
    System.out.println("Value-Key:Gril = " + bidiMap.getKey("Girl"));//Value-Key:Gril = Al
}
2.一對多map:MultiMap

MultiMap:一個key不在是簡單的指向一個對象,而是一組對象

@Test
public void testMultiMap(){
    //MultiHashMap已經(jīng)廢棄
    MultiMap giftMap = new MultiHashMap();
    giftMap.put("gift", "鮮花");
    giftMap.put("gift", "戒指");
    giftMap.put("gift", "傘");
    List list = (List) giftMap.get("gift");
    System.out.println(list);//[鮮花, 戒指, 傘]

    MultiMap giftMap2 = new MultiValueMap();
    giftMap2.put("gift", "鮮花");
    giftMap2.put("gift", "戒指");
    giftMap2.put("gift", "傘");
    giftMap2.put("boy","ay");
    giftMap2.put("girl","al");
    List list2 = (List) giftMap2.get("gift");
    List list3 = (List)giftMap2.get("boy");
    System.out.println(list2);//[鮮花, 戒指, 傘]
    System.out.println(list3);//[ay]

}
3.固定大小map:LRUMap

LRUMap:大小固定。它不是同步的,也不是線程安全的,新增的元素個數(shù)大于允許的最大集合個數(shù)時,則會執(zhí)行LRU淘汰算法。 所有的元素在LRUMap中會根據(jù)最近使用情況進(jìn)行排序。最近使用的會放在元素的最前面(LRUMap是通過鏈表來存儲元素內(nèi)容). 所以LRUMap進(jìn)行淘汰時只需要刪除鏈表最后一個即可(即header.after所指的元素對象)

影響元素的使用情況的操作:

  • 1.put 當(dāng)新增加一個集合元素對象,則表示該對象是最近被訪問的
  • 2.get 操作會把當(dāng)前訪問的元素對象作為最近被訪問的,會被移到鏈接表頭

注:當(dāng)執(zhí)行containsKey和containsValue操作時,不會影響元素的訪問情況。

@Test
public void testLRUMap(){
    LRUMap lruMap = new LRUMap(2);
    //因?yàn)長RUMap是非線程安全,所以可以使用
    // Collections.synchronizedMap(map)來保證線程安全
    Map map = Collections.synchronizedMap(lruMap);
    lruMap.put("boy", "ay");
    lruMap.put("girl", "al");
    lruMap.get("boy");//最近使用
    lruMap.put("person", "person");
    System.out.println(lruMap);//{boy=ay, person=person}
}
4.多個關(guān)鍵字經(jīng)過組合映射map:MultiKeyedMap

根據(jù)API文檔,MultiKeyedMap可以通過下面方式進(jìn)行什么:

//創(chuàng)建一個排序的map

  • MultiKeyMap.decorate(new LinkedMap()) creates an ordered map.

  • MultiKeyMap.decorate(new LRUMap()) creates an least recently used map.

  • MultiKeyMap.decorate(new ReferenceMap()) creates a garbage collector sensitive map.

      @Test
      public void testMultiKeyMap(){
          //初始化類
          MultiKeyMap multiKeyMap = MultiKeyMap.decorate(new LinkedMap());
          multiKeyMap.put(1,1,2,"112");
          multiKeyMap.put(1,1,3,"113");
          multiKeyMap.put(1,2,1,"121");
          multiKeyMap.put(1,2,2,"122");
          multiKeyMap.put(1,3,1,"131");
          //查找一個值:由1,1,2這3個key可以獲得唯一的value值
          String value = (String)multiKeyMap.get(1,1,2);
          System.out.println("value is : " + value);//value is : 112
          String value3 = (String)multiKeyMap.get(2,1,1);
          System.out.println("value3 is : " + value3);//value3 is : null
          String value2 = (String)multiKeyMap.get(1,2,1);
          System.out.println("value2 is " + value2);//value2 is 121
          Object object1 = multiKeyMap.get(1);
          System.out.println("object1 is : " + object1);//object1 is : null
          Object object2 = multiKeyMap.get(1,2);
          System.out.println("object2 is : " + object2);//object2 is : null
      }
    
5.允許Key重復(fù)的Map:IdentityHashMap

IdentityHashMap允許地址不同但內(nèi)容相等作為key值,換句話說,在 IdentityHashMap 中,當(dāng)且僅當(dāng) (k1==k2) 時,才認(rèn)為兩個鍵 k1 和 k2 相等。具體例子如下:

@Test
public void testIdentityMap(){
    class Boy{
        private int id;
        private String name;
        public Boy(int id, String name) {
            this.id = id;
            this.name = name;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Boy{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Boy boy = (Boy) o;
            if (id != boy.id) return false;
            return name != null ? name.equals(boy.name) : boy.name == null;
        }
        @Override
        public int hashCode() {
            int result = id;
            result = 31 * result + (name != null ? name.hashCode() : 0);
            return result;
        }
    }
    //初始化
    IdentityMap identityMap = new IdentityMap();
    //key是相同的boy對象,內(nèi)存地址不同,但是內(nèi)容相同
    identityMap.put(new Boy(1,"ay"),"ay");
    identityMap.put(new Boy(1,"ay"),"al");
    System.out.println(identityMap);//{Boy{id=1, name='ay'}=al, Boy{id=1, name='ay'}=ay}
    //初始化正常map
    Map map = new HashedMap();
    //因?yàn)槲覀冇兄貙慼ashCode方法和toString方法
    map.put(new Boy(1,"ay"),"ay");
    map.put(new Boy(1,"ay"),"al");
    System.out.println(map);//{Boy{id=1, name='ay'}=al}
}
6.線程安全的map:ConcurrentMap

ConcurrentMap,是線程安全的。更多的例子可以百度。

參考文章

【1】Apache commons 之 Collections :Map
【2】LRUMAP 原理解析
【3】org.apache.commons.collections.map.LRUMap 在cache中的使用

【4】在線文檔
【5】Thinking in Java(Java編程思想)

【6】java 利用Map做緩存一個簡單實(shí)例

【7】MultiKeyedMap方案的實(shí)現(xiàn)

【8】valuelist的應(yīng)用實(shí)踐之二: 實(shí)現(xiàn)多鍵值的map

【9】允許Key重復(fù)的Map - IdentityHashMap

讀書感悟

《東京奇譚集》村上春樹

  • 有形的東西和無形的東西——假如必須選其中一個,那么就選無形的!這是我的規(guī)則。碰壁的時候我總是遵循這一規(guī)則,長遠(yuǎn)看來,我想所產(chǎn)生的結(jié)果是好的,哪怕當(dāng)時難以忍受。
  • 歲月這東西總是要按時帶走它要帶走的部分。
唯美圖片

經(jīng)典故事

【一士兵遭到敵軍突襲后逃到了山洞。敵軍在身后緊追,他躲在洞中祈禱不被敵人發(fā)現(xiàn)。
突然胳膊被狠狠地蟄了一下,原來是只蜘蛛,他剛要捏死,突然心生憐憫,就放了它。
不料蜘蛛爬到洞口織了一張新網(wǎng),敵軍追到山洞見到完好的蜘蛛網(wǎng),猜想洞中無人就走了。
啟示:很多時候,幫助別人同時也是在幫助自己】

其他

如果有帶給你一絲絲小快樂,就讓快樂繼續(xù)傳遞下去,歡迎點(diǎn)贊、頂、歡迎留下寶貴的意見、多謝支持!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,699評論 19 139
  • java筆記第一天 == 和 equals ==比較的比較的是兩個變量的值是否相等,對于引用型變量表示的是兩個變量...
    jmychou閱讀 1,658評論 0 3
  • 一、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對于byte類型而言...
    龍貓小爺閱讀 4,476評論 0 16
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 4,036評論 0 11
  • 慧眼看世界 透過批評的眼睛看,世界充滿了有缺陷過失的人;透過傲慢的眼睛看,這世界充滿了低賤愚癡的人;透過智慧的眼睛...
    xcy無名閱讀 392評論 0 0

友情鏈接更多精彩內(nèi)容