開心一笑
【不要對一個程序員說:你的代碼有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編程思想)
【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)贊、頂、歡迎留下寶貴的意見、多謝支持!