十一(二)、集合之Map

1、Map的實現類的結構

  Map:雙列數據,存儲key--value對的數據 -----相似於高中的函數 y = f(x)html

使用Set存儲全部的key,key所在的類要重寫equals()和hashCode()的方法;(以HashMap爲例說的)node

  一、HashMap:

  • 做爲Map的主要實現類;線程不安全,能夠存儲null的key和value;
  • HashMap的底層:數組+鏈表(jdk7及以前)算法

       數組+鏈表+紅黑樹(jdk8)數組

  • 子類:LinkedHashMap:保證在遍歷map元素時,能夠按照添加的順序實現遍歷;

   a、緣由是:在原有的hashmap底層結構基礎上,添加了一堆指針,指向前一個和後一個元素安全

   b、對於頻繁的遍歷操做,此類執行效率更高;ide

測試代碼:函數

 1 @Test
 2     public void test() {
 3         Map hashMap = new HashMap();
 4         hashMap.put(null, null);
 5         hashMap.put(123, "AA");
 6         hashMap.put(456, "BB");
 7         hashMap.put(789, "CC");
 8         System.out.println(hashMap);
 9         
10         LinkedHashMap linkedHashMap = new LinkedHashMap();
11         linkedHashMap.put(null, null);
12         linkedHashMap.put(123, "AA");
13         linkedHashMap.put(456, "BB");
14         linkedHashMap.put(789, "CC");
15         System.out.println(linkedHashMap);
16         
17         Hashtable hashtable = new Hashtable();
18 //        hashtable.put(null, null);//會報錯哦
19         
20     }

這裏的測試

System.out.println(hashMap),無序輸出;
System.out.println(linkedHashMap);按插入屬性輸出

  二、TreeMap:

  • 保證按照添加的key value 對進行排序,實現排序遍歷;(須要向tree添加 key-value ,要求key必須是同一個類的對象
  • 此時使用考慮key的天然排序和定製排序;
  • 底層使用紅黑樹;

  三、Hashtable:

  • 做爲古老的實現類;線程安全;不能夠存儲null的key和value;
  • 子類:Properties:經常使用來處理配置文件; key&value 都是Strin 

  4.思惟導圖:

  腦圖查看地址http://www.javashuo.com/article/p-hfdcmnyd-vk.htmlthis

2、Map結構的理解

  一、Map中的key:無序的、不可重複的:spa

    使用Set存儲全部的key,key所在的類要重寫equals()和hashCode()的方法;(以HashMap爲例說的)

  二、Map中的value:無序的可重複的;

  三、使用Collection存儲全部值;所在類須要重寫equals()方法;

  四、一個key-value 構成了一個Entry對象

  五、Map中的Entry:無序的、不可重複的,使用Set存儲全部的entry;

  

3、HashMap底層實現原理:(以jdk7說明)

一、實現原理:

1  HashMap map = new HashMap();//在實例化之後,底層建立了長度爲16的一維數組Entry[] table;
2 
3   ...//可能已經指向過屢次put
4 
5   map.put(key1,value1);

  首先:調用key1所在類的hashCode()計算key1的哈希值;此哈希值通過某種算法計算後,獲得在Entry數組中的存放位置;

    若是此位置上的數據爲空;此時key1,value1的添加成功;--------狀況1

    若是此位置上的數據不爲空,(意味着此位置存在或一個或多個數據(以鏈表形式存在))

      比較key1和已經存在的一個或者多個數據的哈希值

       若是key1和已經存在的一個或多個數據的哈希值不一樣,則此時key1,value1的添加成功;--------狀況2

       若是key1和已經存在的某個數據(key2-value2)的哈希值相同,則調用key1所在類的equals方法,

  若果返回true,則value1替換

  若返回false,則key1,value1的添加成功;--------狀況3

  對於添加成功的狀況2和狀況3而言,key1-value1與已經存在指定位置上索引位置上數據以鏈表形式存儲;

  

  在不斷添加的過程當中,會涉及到擴容問題;默認的擴容方式:當超出臨界值且存放位置不爲空,擴容爲原來容量的2倍,而且將原來的數據複製過來;

  

  jdk8,相較於jdk7;

  1.new HashMap()底層沒有建立一個長度爲16的數組

  2.jdk8底層的數組是:Node[] 而非Entry[];

  3.首次調用put方法,底層建立長度爲16的數組;

  4.jdk7底層結構只有:數組+鏈表,jdk8中底層結構:數組+鏈表+紅黑樹

  當數組的某一個索引位置上的元素以及鏈表形式存在的數據個數》8且當數組的長度>64時,

  此索引位置上的說有數據改成紅黑樹存儲;

  二、各常量說明:

  •   DEFAULT_INITIAL_CAPACITY:HashMap的默認容量16;
  •   DEFAULT_LOAD_FACTOR;HashMap默認的加載因子:0.75
  •   threshold:擴容的臨界值:DEFAULT_LOAD_FACTORDEFAULT_INITIAL_CAPACITY  0.7516 = 12
  •   TREEIFY_THRESHOLD:桶中鏈表長度大於該默認值,轉換爲紅黑樹:8
  •   MIN_TREEIFY_CAPACITY:桶中的node被樹話最小的hash表容量:64

4、linkedHashMap的底層實現原理

  • 對於頻繁的添加查找元素,可使用linkedHashMap;  
  • 能夠按插入順序輸出;

  源碼中:沒有put 方法,由於繼承了HashMap;

1   public class LinkedHashMap<K,V>
2 
3     extends HashMap<K,V>
4 
5     implements Map<K,V> 
6 
7     

因此這裏的put仍是HashMap的put方法

linkedHashMap重寫了    newNode

 1 Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
 2 
 3         LinkedHashMap.Entry<K,V> p =
 4 
 5             new LinkedHashMap.Entry<K,V>(hash, key, value, e);
 6 
 7         linkNodeLast(p);
 8 
 9         return p;
10 
11     }

 

 1   static class Entry<K,V> extends HashMap.Node<K,V> {
 2 
 3         Entry<K,V> before, after;//這裏可以記錄添加元素的前後順序;
 4 
 5         Entry(int hash, K key, V value, Node<K,V> next) {
 6 
 7             super(hash, key, value, next);
 8 
 9         }
10 
11     }

  

5、Map的經常使用方法:

  1.添加 刪除 修改操做

  1.   Object put(Object key,Object value);將指定的key-value(添加、修改)到當前map對象中;
  2.   void putAll(Map m),將m中全部的 key-value對放入當前map中
  3.   Object remove(Object key),移除指定的key-value對,並返回value;
  4.   void clear();清空當前map中的全部數據

  二、元素查詢的操做

  1.   Object get(Object key):獲取指定key 對應的value
  2.   boolean containsKey(Object key),是否包含指定的key
  3.   boolean containsValue(Object value):是否包含指定的value;
  4.   int size():返回map中key-value對的個數;
  5.   boolean isEmpty():判斷當前map是否爲空;
  6.   boolean equals(Object obj):判斷當前map和參數對象obj是否相等 

  3.元素操做的方法:

  1.   Set keySet();返回左右能夠構成的Set集合
  2.   Collection values();返回全部values構成的Collection集合;
  3.   Set entrySet():隨會全部key-value對構成的Set集合;

   總結經常使用方法:

  •    添加:put(Object key,Object value)
  •    刪除:remove(Object key)
  •    修改:put(Object key,Object value)
  •    查詢:get(Object key)
  •    遍歷:keySet();
  •    長度 size()
  •    遍歷 

   key-value 的遍歷:entrySet()的遍歷 or keySet()+get(Object key)來遍歷

   key的遍歷:keySet()

   value的遍歷:value();

經常使用方法測試:

 1 /**
 2      *1.添加 刪除 修改操做
 3      * Object put(Object key,Object value);將指定的key-value(添加、修改)到當前map對象中;
 4      * void putAll(Map m),將m中全部的 key-value對放入當前map中
 5      * Object remove(Object key),移除指定的key-value對,並返回value;
 6      * void clear();清空當前map中的全部數據 
 7      * 二、元素查詢的操做
 8      * Object get(Object key):獲取指定key 對應的value
 9      * boolean containsKey(Object key),是否包含指定的key
10      * boolean containsValue(Object value):是否包含指定的value;
11      * int size():返回map中key-value對的個數;
12      * boolean isEmpty():判斷當前map是否爲空;
13      * boolean equals(Object obj):判斷當前map和參數對象obj是否相等;
14      *  Set keySet();返回左右能夠構成的Set集合
15      * Collection values();返回全部values構成的Collection集合;
16      * Set entrySet():隨會全部key-value對構成的Set集合;
17      * 
18      */
19     @Test
20     public void test1() {
21         Map hashMap = new HashMap();
22         //Object put(Object key,Object value)來添加元素
23         hashMap.put(null, null);
24         hashMap.put(123, "AA");
25         hashMap.put(456, "BB");
26         hashMap.put(789, "CC");
27         System.out.println("hashMap:"+hashMap);
28         // void putAll(Map m),將m中全部的 key-value對放入當前map中
29         Map newHashMap = new HashMap();
30         newHashMap.putAll(hashMap);
31         System.out.println("newHashMap:"+newHashMap);//全部hashMap中的數據放入了newHashMap中;
32         
33         System.out.println("newHashMap的equals方法:"+newHashMap.equals(hashMap));
34         
35         hashMap.remove(123);
36         System.out.println("hashMap的remove方法:"+hashMap);
37         
38         hashMap.clear();//
39         System.out.println("hashMap的clear方法:"+hashMap);//{},而不是null
40         
41         Object obj = newHashMap.get(123);
42         System.out.println("newHashMap的get方法:"+obj);
43         
44         boolean flag1 = newHashMap.containsKey("AA");
45         System.out.println("newHashMap的containsKey方法:"+flag1);
46         
47         boolean flag2 = newHashMap.containsValue("AA");
48         System.out.println("newHashMap的containsValue方法:"+flag2);
49         
50         System.out.println("newHashMap的size方法:"+newHashMap.size());
51         
52         System.out.println("newHashMap的isEmpty方法:"+newHashMap.isEmpty());//就是判斷size()是否爲0
53         
54         System.out.println("newHashMap的keySet方法:"+newHashMap.keySet());
55         //遍歷全部的key
56         Set keySet = newHashMap.keySet();
57         Iterator iterator = keySet.iterator();
58         while(iterator.hasNext()) {
59             System.out.println("遍歷全部的key:"+iterator.next());
60         }
61         
62         System.out.println("newHashMap的values方法:"+newHashMap.values());
63         //遍歷全部的values
64         Collection values = newHashMap.values();
65         Iterator iterator2 = values.iterator();
66         while(iterator2.hasNext()) {
67             System.out.println("遍歷全部的values:"+iterator2.next());
68         }
69         
70         System.out.println("newHashMap的entrySet方法:"+newHashMap.entrySet());
71         //遍歷全部的entrySet
72         Set entrySet = newHashMap.entrySet();
73         Iterator iterator3 = entrySet.iterator();
74         while(iterator3.hasNext()) {
75             Entry entry = (Entry) iterator3.next();
76             System.out.println(entry.getKey()+"--->"+entry.getValue());//輸出鍵值對;
77         }
78         
79         //輸出鍵值對
80         Set keySet1 = newHashMap.keySet();
81         Iterator iterator4 = keySet.iterator();
82         while(iterator4.hasNext()) {
83             Object key = iterator4.next();
84             System.out.println(key+"--->"+newHashMap.get(key));//輸出鍵值對;
85         }
86         
87     }

 

6、TreeMap中的排序:

  1.    須要向tree添加 key-value ,要求key必須是同一個類的對象
  2.    由於要按照key 排序(天然排序、定製排序)

測試代碼:

 1 //定製排序
 2     @Test
 3     public void test2() {
 4         Comparator com = new Comparator<Person>() {
 5 
 6             @Override
 7             public int compare(Person o1, Person o2) {
 8                 if(o1.getAge()-o2.getAge()>=0) {
 9                     return 1;
10                 }
11                 return -1;
12             }
13         };
14         TreeMap treeMap = new TreeMap(com);
15         treeMap.put( new Person("joy",30), new Object());
16         treeMap.put(new Person("tom",31), new Object());
17         treeMap.put(new Person("lucy",18), new Object());
18         treeMap.comparator();
19         Iterator iterator = treeMap.keySet().iterator();
20         while(iterator.hasNext()) {
21             System.out.println(iterator.next());
22         }
23         
24     }
25     
26     //天然排序;
27     @Test
28     public void test3() {
29         TreeMap treeMap = new TreeMap();
30         treeMap.put( new Person("joy",30), new Object());
31         treeMap.put(new Person("tom",31), new Object());
32         treeMap.put(new Person("lucy",18), new Object());
33         Iterator iterator = treeMap.keySet().iterator();
34         while(iterator.hasNext()) {
35             System.out.println(iterator.next());
36         }
37         
38     }

附:

 1 package collection;
 2 
 3 public class Person implements Comparable {
 4 
 5     private String name;
 6     private int age;
 7     public String getName() {
 8         return name;
 9     }
10     public void setName(String name) {
11         this.name = name;
12     }
13     public int getAge() {
14         return age;
15     }
16     public void setAge(int age) {
17         this.age = age;
18     }
19     public Person(String name, int age) {
20         super();
21         this.name = name;
22         this.age = age;
23     }
24     public Person() {
25         super();
26     }
27     @Override
28     public String toString() {
29         return "Person [name=" + name + ", age=" + age + "]";
30     }
31     @Override
32     public int hashCode() {
33         final int prime = 31;//這裏使用31爲了減小衝突、提升算法效率
34         int result = 1;
35         result = prime * result + age;
36         result = prime * result + ((name == null) ? 0 : name.hashCode());
37         return result;
38     }
39     @Override
40     public boolean equals(Object obj) {
41         if (this == obj)
42             return true;
43         if (obj == null)
44             return false;
45         if (getClass() != obj.getClass())
46             return false;
47         Person other = (Person) obj;
48         if (age != other.age)
49             return false;
50         if (name == null) {
51             if (other.name != null)
52                 return false;
53         } else if (!name.equals(other.name))
54             return false;
55         return true;
56     }
57     @Override
58     public int compareTo(Object o) {
59         Person person = (Person)o;
60         if(this.age>person.age) {
61             return -1;
62         }else {
63             return 1;
64         }
65         
66     }
67     
68     
69 }
View Code

7、Properties

  Properties類是Hashtable的子類,該對象用於處理屬性文件

  •   因爲屬性文件裏的key、value都是字符串類型,因此Properties中裏的key和value都是字符串類型
  •   存取數據時,建議使用 setProperty(String key,String value)和 getProperty(String key)

  測試代碼:

 1 //Properties用來處理配置文件,key和value都是字符串類型
 2     @Test
 3     public void test4() throws Exception {
 4         Properties prop = new Properties();
 5         FileInputStream fis = new FileInputStream(new File("testproperties.properties"));//文件:testproperties.properties
 6         prop.load(fis);//加載對應流文件
 7         String name = prop.getProperty("name");
 8         String value = prop.getProperty("password");
 9         System.out.println("name:"+name);
10         System.out.println("value:"+value);
11     }
1 name=tom
2 password=123456
View Code
相關文章
相關標籤/搜索