今天,我向大家介紹集合框架的最后一個(gè)知識(shí)塊:Map集合,Map集合是雙列集合的根接口。我個(gè)人感覺Map集合比Collection集合更重要些,在實(shí)際的項(xiàng)目開發(fā)中,使用Map創(chuàng)建集合非常之多,在框架整合開發(fā)中也會(huì)用到,在后期做Web項(xiàng)目的時(shí)候還會(huì)用到它,原因我不多說。接下來直接看我演示Map集合的案例…在前面我說到了Collection集合,Collection集合是單列集合的根接口,我們學(xué)習(xí)了Collection集合的Set集合和List集合,又介紹和學(xué)習(xí)了Set集合的子集合:HashSet、LinkedHashSet和TreeSet,主要說了它們的功能和用途,學(xué)習(xí)了List集合的子集合:ArrayList、LinkedList和Vector,也介紹它的功能和用途,但其中最重要的是要學(xué)會(huì)怎樣去應(yīng)用,該如何用?嘿嘿,前面的介紹和學(xué)習(xí)那就慢慢領(lǐng)悟吧~接下來,步入我們的正題:介紹和學(xué)習(xí)Map集合。 首先,Map集合它也是一個(gè)接口,上面剛說到,它是雙列集合的根接口。關(guān)于Map集合接口的概述,百度了一下,網(wǎng)上說的是千篇一律。我從Sun官方提供的手冊中,查看API可知: Map集合是:1.將鍵映射到值得對(duì)象;2.是一個(gè)集合不能包含重復(fù)的鍵;3.每個(gè)鍵最多只能映射到一個(gè)值。 那Map接口與Collection接口有什么不同呢? 1.Map接口是雙列的,而Collection接口是單列的; 2.Map的鍵唯一,Collection的子體系Set是唯一的; 3.Map集合的數(shù)據(jù)結(jié)構(gòu)針對(duì)鍵有效,跟值無關(guān),Collection集合的數(shù)據(jù)結(jié)構(gòu)針對(duì)元素有效。 Map集合它處于java.util包下,它的數(shù)據(jù)結(jié)構(gòu)看起來更像多行兩列的表格,每一條數(shù)據(jù)中包含兩個(gè)信息key-value,其中key在Map中不允許重復(fù),重復(fù)指的是equals為true,Map集合它有兩個(gè)子類,一個(gè)是HashMap,一個(gè)是TreeMap,HashMap有一個(gè)子類叫做LinkedHashMap。和Set集合的體系結(jié)構(gòu)非常相似。接下來,我們來看一下Map集合的方法: 1.V put(K k,V v):向Map集合中添加元素 如果鍵是第一次存儲(chǔ),就直接存儲(chǔ)元素,返回null; 如果鍵不是第一次存儲(chǔ),就用值把以前的值替換掉,返回以前的值。 如下程序代碼:
package cn.edu.jit.map;import java.util.HashMap;import java.util.Map;/** * Map * 該數(shù)據(jù)結(jié)構(gòu)看起來更像多行兩列的表格 * 每一條數(shù)據(jù)中包含兩個(gè)信息key-value, * 其中key在Map中不允許重復(fù),重復(fù)指的是equals為true。 * @author Rocky * */public class MapDemo01 { public static void main(String[] args) { /* * Map本身也是一個(gè)接口,是不能實(shí)例化的,我們用它的一個(gè) * 實(shí) * 例叫做:HashMap * 我們通常也讓Map加泛型,給它們的具體類型。 * * * 創(chuàng)建一個(gè)Map * key是字符串,value是整數(shù) */ Map<String,Integer> map = new HashMap<String,Integer>(); //調(diào)用Map的一個(gè)方法叫 put() 可以存放key和value的值。 /* * V put(K k,V v) * 將給定的key與對(duì)應(yīng)的value存入Map中。 * * 若給定的key在Map中不存在,則是添加新內(nèi)容,那么返回的就是被替換的value值。 * 若給定的key在Map中已存在,則是替換value操作,返回值是null。 * */ System.out.PRintln(map);//{} Integer i = map.put("語文", 95); System.out.println(map);//{語文=95} System.out.println(i);//null i = map.put("語文", 99); System.out.println(map);//{語文=99} map.put("英語", 90); map.put("數(shù)學(xué)", 90); map.put("物理", 98); map.put("化學(xué)", 88); System.out.println(map); }}從Map中獲取元素的方式,我們采用Map的get()方法。 2.V get(K k):根據(jù)給定的key獲取對(duì)應(yīng)的value值。 如下程序代碼:
/* * V get(K k) * 根據(jù)給定的key獲取對(duì)應(yīng)的value值 */ Integer num = map.get("英語"); System.out.println("英語" + num); //如果給一個(gè)不存在的key,其結(jié)果如下: /* * 給定一個(gè)Map中不存在的key, * 返回值則為null。 */ num = map.get("高數(shù)"); System.out.println("高數(shù):" + num);//若找不到對(duì)應(yīng)的key值,則返回null"空"3.刪除功能: void clear():移除所有的鍵值對(duì)元素; V remove(Object key):根據(jù)鍵刪除鍵值對(duì)元素,并把值返回。 如下程序代碼:
package cn.edu.jit.map;import java.util.HashMap;import java.util.Map;public class MapDemo02 { public static void main(String[] args) { Map<String, Integer> map = new HashMap<String, Integer>(); map.put("張三", 23); map.put("李四", 24); map.put("王五", 25); map.put("趙六", 26); //根據(jù)鍵刪除元素,返回鍵對(duì)應(yīng)的值 Integer value = map.remove("張三"); System.out.println(value); System.out.println(map); //運(yùn)行結(jié)果: //23 //{趙六=26, 李四=24, 王五=25} }}4.判斷功能: boolean containsKey(K k): 判斷當(dāng)前Map中是否含有給定的key,是否含有是根據(jù)key的equals判斷的,返回值為boolean類型。 boolean containsValue(Object value): 判斷集合是否包含指定的值,返回值為boolean類型。 boolean isEmpty(): 判斷集合是否為空,返回值為boolean類型。 如下代碼程序:
package cn.edu.jit.map;import java.util.HashMap;import java.util.Map;public class MapDemo03 { public static void main(String[] args) { Map<String, Integer> map = new HashMap<String, Integer>(); map.put("張三", 23); map.put("李四", 24); map.put("王五", 25); map.put("趙六", 26); //根據(jù)鍵刪除元素,返回鍵對(duì)應(yīng)的值// Integer value = map.remove("張三");// System.out.println(value); /* * 判斷是否包含傳入的鍵(值) */ System.out.println(map.containsKey("張三"));//true System.out.println(map.containsValue(23));//true System.out.println(map); }}5.int size():返回集合中的鍵值對(duì)的個(gè)數(shù) 如下程序代碼:
package cn.edu.jit.map;import java.util.Collection;import java.util.HashMap;import java.util.Map;public class MapDemo04 { public static void main(String[] args) { Map<String, Integer> map = new HashMap<String, Integer>(); map.put("張三", 23); map.put("李四", 24); map.put("王五", 25); map.put("趙六", 26); Collection<Integer> c = map.values(); System.out.println(c);//[26, 23, 24, 25] System.out.println(map.size());//4 }}上面幾個(gè)方法主要是Map集合的常用方法,接下來我們看hashCode對(duì)Map操作的影響,看如下程序代碼:
package cn.edu.jit.map;import java.util.HashMap;import java.util.Map;/** * hashCode對(duì)Map操作的影響 * @author Rocky * */public class MapDemo02 { public static void main(String[] args) { Map<Point,Integer> map = new HashMap<Point,Integer>(100); Point p = new Point(1,2); map.put(p, 100); boolean contains = map.containsKey(p); System.out.println("包含key:" + contains); System.out.println(map); Integer i = map.get(p); System.out.println(i); System.out.println(p.hashCode()); //內(nèi)容變化了,hashCode值就會(huì)變化 p.setX(2); System.out.println(p.hashCode()); i = map.get(p); System.out.println(i);//null contains = map.containsKey(p); System.out.println("包含key:" + contains);//包含key:false System.out.println(map);//{day05.Point@401=100} map.put(p, 200); System.out.println(map); Integer ii = map.remove(p); System.out.println("刪除的是:" + ii); System.out.println(map); p.setX(1); ii = map.remove(p); System.out.println("刪除的是:" + ii);//null System.out.println(map);//{day05.Point@401=100} }}使用HashMap時(shí)應(yīng)當(dāng)注意,作為key的對(duì)象有以下要求: 1.首先當(dāng)key這個(gè)類重寫了equals方法,那么重寫的hashcode的要求必須滿足; 2.作為key的對(duì)象若存入HashMap后,其會(huì)影響hashcode值得內(nèi)容不要發(fā)生改變,否則可能會(huì)影響Map操作。 下面,我給大家主要介紹遍歷Map的三種方式: 1.遍歷所有的key; 2.遍歷所有的鍵值對(duì)(key-value); 3.遍歷所有的value(不常用) 如下程序代碼:
package cn.edu.jit.map;import java.util.Collection;import java.util.HashMap;import java.util.LinkedHashMap;import java.util.Map;import java.util.Set;import java.util.Map.Entry;/** * 遍歷Map的三種方式: * 1:遍歷所有的key * 2:遍歷所有的鍵值對(duì)(key-value) * 3:遍歷所有的value(不常用) * @author Rocky * */public class MapDemo03 { public static void main(String[] args) { Map<String,Integer> map = new LinkedHashMap<String,Integer>(); map.put("數(shù)學(xué)", 90); map.put("語文", 98); map.put("物理", 85); map.put("化學(xué)", 78); map.put("英語", 92); map.put("體育", 65); map.put("生物", 78); /* * 遍歷所有的key * Set<K> keySet() * 該方法可以獲取Map中所有的Key,并將它們存入一個(gè)Set集合中返回 * 所以,遍歷該集合就等于遍歷所有的key了。 */ Set<String> keySet = map.keySet(); for(String str : keySet) { System.out.println("str:" + str); } /* * 遍歷鍵值對(duì) * Set<Entry> entrySet() * 該方法會(huì)將每一組key-value存入一個(gè)Entry示例中,并將 * 這些Entry實(shí)例存入一個(gè)Set集合并返回 * 我們只需要遍歷該集合,拿到每一個(gè)Entry實(shí)例并獲取其中的key與 * value即可。 * * Entry是Map的一個(gè)內(nèi)部類。 */ //我們Entry里面的泛型兒要和Map中的泛型保持一致! Set<Entry<String,Integer>> entrySet = map.entrySet(); for(Entry<String,Integer> e:entrySet) { String key = e.getKey(); Integer value = e.getValue(); System.out.println(key+":"+value); } /* * 遍歷所有的value * 獲取來的是Collection集合 */ Collection<Integer> values = map.values(); for(Integer value : values) { System.out.println("value:" + value); } }}下面,我們來做一個(gè)案例練習(xí):HashMap集合鍵是Student,值是String。 為什么我們要在雙列集合中要存儲(chǔ)一個(gè)Student呢,Student是什么?它是一個(gè)自定義類。也就是我們想把自定義對(duì)象存儲(chǔ)在HashMap集合中。剛在一開始的時(shí)候我就介紹過,HashMap這個(gè)指針指向的只對(duì)鍵有效,咱們把自定義對(duì)象存儲(chǔ)在它的鍵的位置,就想看它如何保證鍵的唯一。接下來,我們來演示這個(gè)案例,看如下程序代碼: 首先,我們要自定義一個(gè)Student類:
package cn.edu.jit.bean;public class Student { private String name; private int age; public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Studnet [age=" + age + ", name=" + name + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; }}我們創(chuàng)建一個(gè)HashMapDemo05,如下程序:
package cn.edu.jit.map;import java.util.HashMap;import cn.edu.jit.bean.Student;/** * 案例演示: * HashMap集合鍵是Student,值是String的案例。 * 鍵:是學(xué)生對(duì)象,代表每一個(gè)學(xué)生; * 值:是字符串對(duì)象,代表學(xué)生的歸屬地 * @author Rocky * */public class HashMapDemo05 { public static void main(String[] args) { HashMap<Student, String> hm = new HashMap<Student, String>(); hm.put(new Student("錢春華",23), "江蘇南通"); hm.put(new Student("Jolin",24), "江蘇泰州"); hm.put(new Student("Jolin",24), "上海"); hm.put(new Student("二狗",25), "江蘇無錫"); hm.put(new Student("瑤瑤",20), "江蘇南京"); System.out.println(hm); //{Studnet [age=23, name=錢春華]=江蘇南通, Studnet [age=25, name=二狗]=江蘇無錫, Studnet [age=20, name=瑤瑤]=江蘇南京, Studnet [age=24, name=Jolin]=上海} }}接下來,我們來說HashMap有一個(gè)子類叫做LinkedHashMap,它的特點(diǎn)是:底層是鏈表實(shí)現(xiàn)的可以保證怎么存就怎么取。如下代碼:
package cn.edu.jit.map;import java.util.LinkedHashMap;/** * * @author Rocky * */public class LinkedHashMapDemo { public static void main(String[] args) { LinkedHashMap<String, Integer> lhm = new LinkedHashMap<String, Integer>(); lhm.put("張三", 23); lhm.put("李四", 24); lhm.put("趙六", 26); lhm.put("王五", 25); System.out.println(lhm); //{張三=23, 李四=24, 趙六=26, 王五=25} }}說完了LinkedHashMap,我們再來說一說TreeMap,我們來看看TreeMap如何對(duì)鍵唯一,因?yàn)殡p列集合只針對(duì)鍵有效,鍵值得算法是一個(gè)二叉樹,也就是說它可以對(duì)鍵進(jìn)行排序。好,我們來通過這個(gè)案例演示TreeMap集合:鍵是Student,值是:String。如下程序代碼: 首先我們要在Student類實(shí)現(xiàn)Comparable接口,并重寫compareTo方法,貼上代碼:
@Override public int compareTo(Student o) { int num = this.age - o.age; return num == 0 ? this.name.compareTo(o.name) : num; }Student類整個(gè)代碼如下:
package cn.edu.jit.bean;public class Student implements Comparable<Student> { private String name; private int age; public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Studnet [age=" + age + ", name=" + name + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public int compareTo(Student o) { int num = this.age - o.age; return num == 0 ? this.name.compareTo(o.name) : num; }}在創(chuàng)建一個(gè)TreeMapDemo類,代碼如下:
package cn.edu.jit.map;import java.util.TreeMap;import cn.edu.jit.bean.Student;/** * TreeMap集合鍵是Student,值是String * @author Rocky * */public class TreeMapDemo { public static void main(String[] args) { TreeMap<Student, String> tm = new TreeMap<Student, String>(); tm.put(new Student("張三",23), "北京"); tm.put(new Student("李四",24), "上海"); tm.put(new Student("王五",25), "廣州"); tm.put(new Student("趙六",26), "深圳"); System.out.println(tm); //在沒有實(shí)現(xiàn)Comparable接口時(shí),報(bào)了異常,因?yàn)闆]有在Student類實(shí)現(xiàn)Compare這個(gè)接口。 //運(yùn)行結(jié)果:{Studnet [age=23, name=張三]=北京, Studnet [age=24, name=李四]=上海, Studnet [age=25, name=王五]=廣州, Studnet [age=26, name=趙六]=深圳} }}大家覺得很好奇,剛才運(yùn)行結(jié)果的程序是按照對(duì)象比較性進(jìn)行排序的,有沒有比較器呢,我們來看一下,有一個(gè)重構(gòu)方法Comparator去實(shí)現(xiàn),我們通過匿名內(nèi)部類去實(shí)現(xiàn),貼上代碼:
package cn.edu.jit.map;import java.util.Comparator;import java.util.TreeMap;import cn.edu.jit.bean.Student;/** * TreeMap集合鍵是Student,值是String * @author Rocky * */public class TreeMapDemo { public static void main(String[] args) { TreeMap<Student, String> tm = new TreeMap<Student, String>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { //按照姓名去比較 int num = s1.getName().compareTo(s2.getName()); return num == 0 ? s1.getAge() - s2.getAge() : num; } }); tm.put(new Student("張三",23), "北京"); tm.put(new Student("李四",24), "上海"); tm.put(new Student("王五",25), "廣州"); tm.put(new Student("趙六",26), "深圳"); System.out.println(tm); //運(yùn)行結(jié)果:{Studnet [age=23, name=張三]=北京, Studnet [age=24, name=李四]=上海, Studnet [age=25, name=王五]=廣州, Studnet [age=26, name=趙六]=深圳} //我們可以看到,這就按照順序排序打印出來了 }}好了,今天Map集合方法以及它的用途就介紹到這,下面講解HashMap集合嵌套,本文中所有的案例程序都是本人親測過,如有不對(duì)的地方請(qǐng)各位朋友歡迎指正,謝謝了!
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注