zoukankan      html  css  js  c++  java
  • java集合类(五)About Map

    接上篇“java集合类(四)About Set”

         这次学完Map之后,就剩队列的知识,之后有关java集合类的学习就将告一段落,之后可能会有java连接数据库,I/O,多线程,网络编程或Android方面的东西,不过现在还不能确定!  

    • Talk About Map:

    interface Map<key,value>:键值对对象,使用key查找value,就像映射表(关联数组/字典)一样,可以使用一个对象来查找另一个对象

    key:应该是唯一的,不直接接受基本类型,但对应的包装类对象可以

    value:不唯一,即相同的value可对应不同的key,也不直接接受基本类型,包装类则可以,map值也可以是其他容器,包括map本身

    All Known Subinterfaces:
    Bindings, ConcurrentMap<K,V>, ConcurrentNavigableMap<K,V>, LogicalMessageContext, MessageContext, NavigableMap<K,V>, SOAPMessageContext, SortedMap<K,V>
    All Known Implementing Classes:
    AbstractMap, Attributes, AuthProvider, ConcurrentHashMap, ConcurrentSkipListMap, EnumMap, HashMap, Hashtable, IdentityHashMap, LinkedHashMap, PrinterStateReasons, Properties, Provider, RenderingHints, SimpleBindings, TabularDataSupport, TreeMap, UIDefaults, WeakHashMap

     Map接口本身拥有的方法也不是很多,也很容易掌握,常用到的Map子类主要有:HashMap,LinkedHashMap,TreeMap,WeakHashMap,ConcurrentHashMap,IdentityHashMap(这几种Map的可比较见下文),关于前三种Map,他们的特性跟之前在java集合类(四)About Set 的那三种Set很类似,可以联想记忆,而后三种一般初学者(比如我)较少遇到,我只能尽可能找资料,但也不能面面俱到,毕竟只是涉及初级应用,读者若有什么建议,或资料也可告知我,才能丰富其中的内容。下面开始学习:

    • 常见Map的比较:

    1)HashMap:最常用的Map,基于hash(散列表)的实现,可放任意对象;修改equals()的同时也要修改hashCode();插入和查询“键值对”的开销是固定的,可以通过构造器设置容量和负载因子,以调整容器的性能

    2)LinkedHashMap:类似与HashMap,遍历它的顺序是其键值对插入的顺序,或是最近最少使用的次序,只比HashMap慢一点;而在迭代访问时反而更快,因为它使用链表维护内部次序

    3)TreeMap:与TreeSet类似,底层基于红黑树。它是有序的(按键排序),放入其中键对象都要实现Comparable接口/Comparator;它是唯一有返回子树subMap()方法的Map

    4)WeakHashMap:弱键映射,允许释放映射所指向的对象;若映射之外没有引用指向某个键,那么此键可能被垃圾回收器回收

    5)ConcurrentHashMap:一种线程安全的Map,不涉及同步锁

    6)IdentityHashMap:使用==代替equals()对键进行比较的散列映射

    说明:Map中的任何一个键都必须具有一个equals()方法,如若键被用于散列Map,如HashMap,LinkedHashMap,那它还必须具有恰当的hashCode()方法;而键被用于TreeMap,那它则必须实现Comparable

    • About HashMap:
    All Implemented Interfaces:Serializable, Cloneable, Map<K,V>
    Direct Known Subclasses:LinkedHashMap, PrinterStateReasons
    基本方法实例:
    import java.util.*;
    
    public class Mapdemo{
      public static void main(String[] agrs){
          Random r = new Random(47);
           Map<Integer,Integer> m = new HashMap<Integer,Integer>();
           for(int i = 0; i<1000;i++){
        	   int n = r.nextInt(20);
        	   Integer g = m.get(n);
        	   m.put(n, g==null?1:g+1);
           }
           System.out.println(m);
           //constructors
           HashMap<String,String> hm = new HashMap<String,String>(6);
           HashMap<String,String> hm1 = new HashMap<String,String>(hm);
           //the second para is loadfactor
           HashMap<String,Integer> hm2 = new HashMap<String,Integer>(5,1f);
           HashMap<String,List<Integer>> hm3 = new
                                                 HashMap<String,List<Integer>>();           
           
           hm.put("allen", "dog");
           hm.put("jason", "cat");
           hm.put("John", "snake");
           System.out.println(hm);
           System.out.println(hm.containsKey("ketty"));
           System.out.println(hm.containsValue("cat"));
           System.out.println(hm.get("allen"));
           
           hm3.put("integer", new ArrayList(Arrays.asList(1,2,3)));
           System.out.println(hm3);
      }
    }
    

     输出:

    {0=42, 1=44, 2=53, 3=43, 4=44, 5=53, 6=42, 7=53, 8=46, 9=56, 10=58, 11=55, 12=48, 13=55, 14=52, 15=50, 17=50, 16=53, 19=52, 18=51}
    {jason=cat, allen=dog, John=snake}
    false
    true
    dog
    {integer=[1, 2, 3]}

    # 为什么HashMap能够提高查找速度?

    A:HashMap使用了特殊的值(散列码)来取代对键对象的缓慢搜索,散列码是相对唯一的,用以代表对象的int值,它是通过将该对象的某些信息进行转换而生成的;而hashCode()是Object对象中的方法,所以所有的对象都能产生散列码

    大家若对HashMap的实现原理感兴趣,我可以推荐一篇博文:HashMap的实现原理 (转自csdn  @AlphaWang)

    • About SortedMap:
    All Superinterfaces:Map<K,V>
    All Known Subinterfaces:ConcurrentNavigableMap<K,V>, NavigableMap<K,V>
    All Known Implementing Classes:ConcurrentSkipListMap, TreeMap
    最常用实现类的为TreeMap,实例如下:
    public void sortedmapdemo(){
    	TreeMap<Integer,String> t = new TreeMap<Integer,String>();
    	t.put(1,"apple");
    	t.put(2, "peal");
    	t.put(3, "banana");
    	t.put(4, "orange");
    	System.out.println(t);
    	System.out.println(t.firstKey());
    	System.out.println(t.lastKey());
    	System.out.println(t.subMap(2, 4));
    	System.out.println(t.headMap(3));
    	System.out.println(t.tailMap(2));
    	Iterator<Integer> it = t.keySet().iterator();
    	for(int i = 0; i<4;i++){
    	   System.out.println(it.next());
            }
    }
    

      输出:

    {1=apple, 2=peal, 3=banana, 4=orange}
    1
    4
    {2=peal, 3=banana}
    {1=apple, 2=peal}
    {2=peal, 3=banana, 4=orange}
    1
    2
    3
    4

    说明:TreeMap的其他方法,如构造方法,comparator()等,可参考JDK文档说明使用!

    • About LinkedHashMap:
    public void linkedhashmapdemo(){
    	LinkedHashMap<Integer,String> lm = 
                           new LinkedHashMap<Integer,String>();
    	lm.put(1, "bed");
    	lm.put(2, "light");
    	lm.put(3, "desk");
    	lm.put(4, "book");
    	System.out.println(lm);
    	//LRU(least-recently-used) order:按使用频率排序
    	lm = new LinkedHashMap<Integer,String>(10,0.75f,true);
    	lm.put(1, "bed");
    	lm.put(2, "light");
    	lm.put(3, "desk");
    	lm.put(4, "book");
    	System.out.println(lm);
    	for(int i = 1;i<3;i++)
    		lm.get(i);   //使用频率高的会放在队列后
    	System.out.println(lm);
    	lm.get(1);  //频率最高排最后
    	System.out.println(lm);				
    }
    

    输出:

    {1=bed, 2=light, 3=desk, 4=book}
    {1=bed, 2=light, 3=desk, 4=book}
    {3=desk, 4=book, 1=bed, 2=light}
    {3=desk, 4=book, 2=light, 1=bed}

    说明:上面HashMap和LinkedHashMap代码中的构造方法中涉及到loadfactor(装填因子)(构造方法中为float型),在数据结构中,hash表的装填因子定义为:

          α = 表中记录数/hash表长     即α表示hash表的装满程度,α值越小,发生冲突的可能性就越小,即rehash的几率就越低,反之,...

        下一节是关于“java集合类(六)About Queue”,敬请期待!

    ###    学习从来都是一个过程,对对错错对对...若文中有错误,还望读者批评指出      ###

  • 相关阅读:
    Populating Next Right Pointers in Each Node
    Reverse Linked List
    Reverse Linked List II
    Triangle
    Surrounded Regions
    Effective_STL 学习笔记(十九) 了解相等和等价的区别
    Effective_STL 学习笔记(十八) 避免使用 vector<bool>
    Effective_STL 学习笔记(十七) 使用 “交换技巧” 来修整过剩的容量
    Effective_C++ (条款02) 尽量以 const,enum,inline替换 #define
    Effective_C++ (条款01) 视 C++ 为一个语言联邦
  • 原文地址:https://www.cnblogs.com/allenpengyu/p/3465678.html
Copyright © 2011-2022 走看看