优雅编程之这样使用Map,你就“正常”了 千万不要这么说之幽默笑话: 不要对一个程序员说:你的代码有bug 他的第一个反应是:1.你的环境有问题吧;2.傻逼你会用吗? 如果你委婉的说:你这个程序和预期的有点不一样,你看是不是我的使用方法有问题。 他本能的会想:操,是不是出bug了。。。 提出问题 项目中一些不为人知却好用的集合map有哪些??? 解决问题 双向map:DualHashBidiMap DualHashBidiMap可以通过key找到value,也可以通过value找到key @TestpublicvoidtestDualHashBidiMap(){ //双向map BidiMapbidiMap=newDualHashBidiMap(); 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} 一对多map:MultiMap MultiMap:一个key不在是简单的指向一个对象,而是一组对象 @TestpublicvoidtestMultiMap(){ //MultiHashMap已经废弃 MultiMapgiftMap=newMultiHashMap(); giftMap.put("gift","鲜花"); giftMap.put("gift","戒指"); giftMap.put("gift","伞"); Listlist=(List)giftMap.get("gift"); System.out.println(list);//[鲜花,戒指,伞] MultiMapgiftMap2=newMultiValueMap(); giftMap2.put("gift","鲜花"); giftMap2.put("gift","戒指"); giftMap2.put("gift","伞"); giftMap2.put("boy","ay"); giftMap2.put("girl","al"); Listlist2=(List)giftMap2.get("gift"); Listlist3=(List)giftMap2.get("boy"); System.out.println(list2);//[鲜花,戒指,伞] System.out.println(list3);//[ay]} 固定大小map:LRUMap LRUMap:大小固定。它不是同步的,也不是线程安全的,新增的元素个数大于允许的最大集合个数时,则会执行 LRU淘汰算法 。所有的元素在LRUMap中会根据最近使用情况进行排序。最近使用的会放在元素的最前面(LRUMap是通过链表来存储元素内容).所以LRUMap进行淘汰时只需要删除链表最后一个即可(即header.after所指的元素对象) 影响元素的使用情况的操作: 1.put当新增加一个集合元素对象,则表示该对象是最近被访问的 2.get操作会把当前访问的元素对象作为最近被访问的,会被移到链接表头 注:当执行containsKey和containsValue操作时,不会影响元素的访问情况。 @TestpublicvoidtestLRUMap(){ LRUMaplruMap=newLRUMap(2); //因为LRUMap是非线程安全,所以可以使用 //Collections.synchronizedMap(map)来保证线程安全 Mapmap=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}} 多个关键字经过组合映射map:MultiKeyedMap 根据API文档,MultiKeyedMap可以通过下面方式进行什么: //创建一个排序的map -MultiKeyMap.decorate(newLinkedMap())createsanorderedmap. -MultiKeyMap.decorate(newLRUMap())createsanleastrecentlyusedmap. -MultiKeyMap.decorate(newReferenceMap())createsagarbagecollectorsensitivemap. @Test publicvoidtestMultiKeyMap(){ //初始化类 MultiKeyMapmultiKeyMap=MultiKeyMap.decorate(newLinkedMap()); 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值 Stringvalue=(String)multiKeyMap.get(1,1,2); System.out.println("valueis:"+value);//valueis:112 Stringvalue3=(String)multiKeyMap.get(2,1,1); System.out.println("value3is:"+value3);//value3is:null Stringvalue2=(String)multiKeyMap.get(1,2,1); System.out.println("value2is"+value2);//value2is121 Objectobject1=multiKeyMap.get(1); System.out.println("object1is:"+object1);//object1is:null Objectobject2=multiKeyMap.get(1,2); System.out.println("object2is:"+object2);//object2is:null } 允许Key重复的Map:IdentityHashMap IdentityHashMap允许地址不同但内容相等作为key值,换句话说,在IdentityHashMap中,当且仅当(k1==k2)时,才认为两个键k1和k2相等。具体例子如下: @TestpublicvoidtestIdentityMap(){ classBoy{ privateintid; privateStringname; publicBoy(intid,Stringname){ this.id=id; this.name=name; } publicintgetId(){ returnid; } publicvoidsetId(intid){ this.id=id; } publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } @Override publicStringtoString(){ return"Boy{"+ "id="+id+ ",name='"+name+'''+ '}'; } @Override publicbooleanequals(Objecto){ if(this==o)returntrue; if(o==null||getClass()!=o.getClass())returnfalse; Boyboy=(Boy)o; if(id!=boy.id)returnfalse; returnname!=null?name.equals(boy.name):boy.name==null; } @Override publicinthashCode(){ intresult=id; result=31*result+(name!=null?name.hashCode():0); returnresult; } } //初始化 IdentityMapidentityMap=newIdentityMap(); //key是相同的boy对象,内存地址不同,但是内容相同 identityMap.put(newBoy(1,"ay"),"ay"); identityMap.put(newBoy(1,"ay"),"al"); System.out.println(identityMap);//{Boy{id=1,name='ay'}=al,Boy{id=1,name='ay'}=ay} //初始化正常map Mapmap=newHashedMap(); //因为我们有重写hashCode方法和toString方法 map.put(newBoy(1,"ay"),"ay"); map.put(newBoy(1,"ay"),"al"); System.out.println(map);//{Boy{id=1,name='ay'}=al}} 线程安全的map:ConcurrentMap ConcurrentMap,是线程安全的。 更多的例子可以关注“动力节点Java学院”微信公众号获取。现在报名培训,可免费参加Java初级课程,亲身体验学习氛围。 |
小黑屋|在路上
( 蜀ICP备15035742号-1 )
GMT+8, 2025-7-10 10:01
Copyright 2015-2025 djqfx