千鋒教育Java入門全套視頻教程(java核心技術(shù),適合java零基礎(chǔ),Java

Map接口簡介
今天來看一看map集合,map映射接口,用于存放鍵值對,<key,value>,通過key來查找value,顧名思義key不能為空,唯一且不重復(fù),不然底層怎么查呢!
可以從圖中看出Map為單獨(dú)的接口,他和Collection有什么區(qū)別呢?
Map和Collection在集合中并列存在。
Map集合是雙列的,鍵值對,而Collection是單列集合
Map存儲(chǔ)元素使用put方法,Collection使用Put方法。
Map遍歷沒有直接取出元素的方法,而是先轉(zhuǎn)成Set集合,再通過迭代獲取元素。
--Map常用方法
–Map應(yīng)用
添加:使用HashMap。立了學(xué)生姓名和年齡之間的映射關(guān)系。并試圖添加重復(fù)的鍵
復(fù)制代碼
??public static void main(String[] args) {
????// 定義一個(gè)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方式??添加重復(fù)的鍵值(值不同),會(huì)覆蓋掉前面key值相同的值
????System.out.println(map1);??
????
????Map<String, Integer> map2 = new HashMap<String, Integer>();??
????map2.put("張三豐", 100);??
????map2.put("虛竹", 20);??
????System.out.println("map2:" + map2);??
????// 從指定映射中將所有映射關(guān)系復(fù)制到此映射中。??
????map1.putAll(map2);??
????System.out.println("map1:" + map1);??
??}??
??public static void main(String[] args) {??
// 刪除:??
????// remove() 刪除關(guān)聯(lián)對象,指定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);??
????//第三種只遍歷鍵或者值,通過加強(qiáng)for循環(huán)
????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());
????}
????
??}
底層是哈希表數(shù)據(jù)結(jié)構(gòu),線程是不同步的,可以存入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相同不會(huì)覆蓋
????
??????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可以對集合中的鍵進(jìn)行排序。如何實(shí)現(xiàn)鍵的排序?
方式一:元素自身具備比較性
和TreeSet一樣原理,需要讓存儲(chǔ)在鍵位置的對象實(shí)現(xiàn)Comparable接口,重寫compareTo方法,也就是讓元素自身具備比較性,這種方式叫做 元素的自然排序也叫做默認(rèn)排序。
方式二:容器具備比較性
當(dāng)元素自身不具備比較性,或者自身具備的比較性不是所需要的。那么此時(shí)可以讓容器自身具備。需要定義一個(gè)類實(shí)現(xiàn)接口Comparator,重 寫compare方法,并將該接口的子類實(shí)例對象作為參數(shù)傳遞給TreeMap集合的構(gòu)造方法。
注意:當(dāng)Comparable比較方式和Comparator比較方式同時(shí)存在時(shí),以Comparator的比較方式為主;
注意:在重寫compareTo或者compare方法時(shí),必須要明確比較的主要條件相等時(shí)要比較次要條件。(假設(shè)姓名和年齡一致的人為相同的人, 如果想要對人按照年齡的大小來排序,如果年齡相同的人,需要如何處理?不能直接return 0,以為可能姓名不同(年齡相同姓名不同的人 是不同的人)。此時(shí)就需要進(jìn)行次要條件判斷(需要判斷姓名),只有姓名和年齡同時(shí)相等的才可以返回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("李四"));
??}?
}?
??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的元素不可重復(fù),Map的鍵不可重復(fù),如果存入重復(fù)元素如何處理
Set元素重復(fù)元素不能存入add方法返回false
Map的重復(fù)健將覆蓋舊鍵,將舊值返回。