
--Map接口簡介
今天來看一看map集合,map映射接口,用於存放鍵值對,<key,value>,通過key來查找value,顧名思義key不能為空,唯一且不重復,不然底層怎么查呢!
可以從圖中看出Map為單獨的接口,他和Collection有什么區別呢?
- Map和Collection在集合中並列存在。
- Map集合是雙列的,鍵值對,而Collection是單列集合
- Map存儲元素使用put方法,Collection使用Put方法。
- Map遍歷沒有直接取出元素的方法,而是先轉成Set集合,再通過迭代獲取元素。
--Map常用方法
--Map應用
- 添加:使用HashMap。立了學生姓名和年齡之間的映射關系。並試圖添加重復的鍵
public static void main(String[] args) { // 定義一個Map的容器對象 Map<String, Integer > map1 = new HashMap<String, Integer >(); map1.put("jack", 20); map1.put("rose", 18); map1.put("lucy", 17); map1.put("java", 25); // map1.put("jack", 30); 在沒有hashCode和equals方式 添加重復的鍵值(值不同),會覆蓋掉前面key值相同的值 System.out.println(map1); Map<String, Integer> map2 = new HashMap<String, Integer>(); map2.put("張三豐", 100); map2.put("虛竹", 20); System.out.println("map2:" + map2); // 從指定映射中將所有映射關系復制到此映射中。 map1.putAll(map2); System.out.println("map1:" + map1); }
- 刪除:
public static void main(String[] args) { // 刪除: // remove() 刪除關聯對象,指定key對象 // clear() 清空集合對象 Map<String, Integer> map1 = new HashMap<String, Integer>(); map1.put("jack", 20); map1.put("rose", 18); map1.put("lucy", 17); map1.put("java", 25); System.out.println(map1); // 指定key,返回刪除的鍵值對映射的值。 map1.remove("java"); System.out.println(map1); map1.clear(); System.out.println("map1:" + map1); }
-
獲取:
public static void main(String[] args) { // 獲取: // V get(Object key) 通過指定的key對象獲取value對象 // int size() 獲取容器的大小 Map<String, Integer> map1 = new HashMap<String, Integer>(); map1.put("jack", 20); map1.put("rose", 18); map1.put("lucy", 17); map1.put("java", 25); System.out.println(map1); // V get(Object key) 通過指定的key對象獲取value對象 System.out.println("value:" + map1.get("jack")); // int size() 獲取容器的大小 System.out.println("map.size:" + map1.size()); }
- 判斷:
public static void main(String[] args) { // 判斷: // boolean isEmpty() 判斷集合是否為空 長度為0返回true否則false // boolean containsKey(Object key) 判斷集合中是否包含指定的key // boolean containsValue(Object value) Map<String, Integer> map1 = new HashMap<String, Integer>(); map1.put("jack", 20); map1.put("rose", 18); map1.put("lucy", 17); map1.put("java", 25); System.out.println(map1); System.out.println("isEmpty:" + map1.isEmpty()); System.out.println("containskey:" + map1.containsKey("jack")); System.out.println("containsvalues:" + map1.containsValue(100)); }
遍歷Map的4中方式:
- 第一種:
public static void main(String[] args) { //遍歷Map 第一種方式 Map<String, Integer> map1 = new HashMap<String, Integer>(); map1.put("jack", 20); map1.put("rose", 18); map1.put("lucy", 17); map1.put("java", 25); //通過 map1.keySet() 獲取key 通過key 找到value for (String key : map1.keySet()) { Integer value = map1.get(key); System.out.println("key : "+key+" value : "+value); } }
- 第二種:
public static void main(String[] args) { //遍歷Map 第二種方式 Map<String, Integer> map1 = new HashMap<String, Integer>(); map1.put("jack", 20); map1.put("rose", 18); map1.put("lucy", 17); map1.put("java", 25); //通過Map.Entry(String,Integer) 獲取,然后使用entry.getKey()獲取到鍵,通過entry.getValue()獲取到值 for(Map.Entry<String, Integer> entry : map1.entrySet()){ System.out.println("鍵 key :"+entry.getKey()+" 值value :"+entry.getValue()); } }
- 第三種:
//遍歷Map 第三種方式 Map<String, Integer> map1 = new HashMap<String, Integer>(); map1.put("jack", 20); map1.put("rose", 18); map1.put("lucy", 17); map1.put("java", 25); //第三種只遍歷鍵或者值,通過加強for循環 for(String s1:map1.keySet()){//遍歷map的鍵 System.out.println("鍵key :"+s1); } for(Integer s2:map1.values()){//遍歷map的值 System.out.println("值value :"+s2); } System.out.println("===================================="); }
-
第四種:
public static void main(String[] args) { //遍歷Map 第一種方式 Map<String, Integer> map1 = new HashMap<String, Integer>(); map1.put("jack", 20); map1.put("rose", 18); map1.put("lucy", 17); map1.put("java", 25); //第四種Iterator遍歷獲取,然后獲取到Map.Entry<String, String>,再得到getKey()和getValue() Iterator<Map.Entry<String, Integer>> it=map1.entrySet().iterator(); while(it.hasNext()){ Map.Entry<String, Integer> entry=it.next(); System.out.println("鍵key :"+entry.getKey()+" value :"+entry.getValue()); } }
HashMap
- 底層是哈希表數據結構,線程是不同步的,可以存入null鍵,null值。要保證鍵的唯一性,需要覆蓋hashCode方法,和equals方法。
案例:自定義對象作為Map的鍵。
public class Demo3 { public static void main(String[] args) { HashMap<Person, String> hm = new HashMap<Person, String>(); hm.put(new Person("jack", 20), "1001"); hm.put(new Person("rose", 18), "1002"); hm.put(new Person("lucy", 19), "1003"); hm.put(new Person("hmm", 17), "1004"); hm.put(new Person("ll", 25), "1005"); System.out.println(hm); System.out.println(hm.put(new Person("rose", 18), "1006")); //重寫hashCode和equalse后key相同不會覆蓋 Set<Entry<Person, String>> entrySet = hm.entrySet(); Iterator<Entry<Person, String>> it = entrySet.iterator(); while (it.hasNext()) { Entry<Person, String> next = it.next(); Person key = next.getKey(); String value = next.getValue(); System.out.println(key + " = " + value); } } } class Person { private String name; private int age; Person() { } public Person(String name, int age) { 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 int hashCode() { return this.name.hashCode() + age * 37; } @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person p = (Person) obj; return this.name.equals(p.name) && this.age == p.age; } else { return false; } } @Override public String toString() { return "Person@name:" + this.name + " age:" + this.age; } } }
TreeMap
TreeMap的排序,TreeMap可以對集合中的鍵進行排序。如何實現鍵的排序?
方式一:元素自身具備比較性
和TreeSet一樣原理,需要讓存儲在鍵位置的對象實現Comparable接口,重寫compareTo方法,也就是讓元素自身具備比較性,這種方式叫做 元素的自然排序也叫做默認排序。
方式二:容器具備比較性
當元素自身不具備比較性,或者自身具備的比較性不是所需要的。那么此時可以讓容器自身具備。需要定義一個類實現接口Comparator,重 寫compare方法,並將該接口的子類實例對象作為參數傳遞給TreeMap集合的構造方法。
注意:當Comparable比較方式和Comparator比較方式同時存在時,以Comparator的比較方式為主;
注意:在重寫compareTo或者compare方法時,必須要明確比較的主要條件相等時要比較次要條件。(假設姓名和年齡一致的人為相同的人, 如果想要對人按照年齡的大小來排序,如果年齡相同的人,需要如何處理?不能直接return 0,以為可能姓名不同(年齡相同姓名不同的人 是不同的人)。此時就需要進行次要條件判斷(需要判斷姓名),只有姓名和年齡同時相等的才可以返回0.)
通過return 0來判斷唯一性。
public class Demo4 {
public static void main(String[] args) {
TreeMap<String, Integer> tree = new TreeMap<String, Integer>();
tree.put("張三", 19);
tree.put("李四", 20);
tree.put("王五", 21);
tree.put("趙六", 22);
tree.put("周七", 23);
tree.put("張三", 24);
System.out.println(tree);
System.out.println("張三".compareTo("李四"));//-2094
}
}
自定義元素排序
public class Demo3 { public static void main(String[] args) { TreeMap<Person, String> hm = new TreeMap<Person, String>( new MyComparator()); hm.put(new Person("jack", 20), "1001"); hm.put(new Person("rose", 18), "1002"); hm.put(new Person("lucy", 19), "1003"); hm.put(new Person("hmm", 17), "1004"); hm.put(new Person("ll", 25), "1005"); System.out.println(hm); System.out.println(hm.put(new Person("rose", 18), "1006")); Set<Entry<Person, String>> entrySet = hm.entrySet(); Iterator<Entry<Person, String>> it = entrySet.iterator(); while (it.hasNext()) { Entry<Person, String> next = it.next(); Person key = next.getKey(); String value = next.getValue(); System.out.println(key + " = " + value); } } } class MyComparator implements Comparator<Person> { @Override public int compare(Person p1, Person p2) { if (p1.getAge() > p2.getAge()) { return -1; } else if (p1.getAge() < p2.getAge()) { return 1; } return p1.getName().compareTo(p2.getName()); } } class Person implements Comparable<Person> { private String name; private int age; Person() { } public Person(String name, int age) { 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 int hashCode() { return this.name.hashCode() + age * 37; } @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person p = (Person) obj; return this.name.equals(p.name) && this.age == p.age; } else { return false; } } @Override public String toString() { return "Person@name:" + this.name + " age:" + this.age; } @Override public int compareTo(Person p) { if (this.age > p.age) { return 1; } else if (this.age < p.age) { return -1; } return this.name.compareTo(p.name); } }
注意:Set的元素不可重復,Map的鍵不可重復,如果存入重復元素如何處理
Set元素重復元素不能存入add方法返回false
Map的重復健將覆蓋舊鍵,將舊值返回。

