1. 程式人生 > >Java Map集合的詳解

Java Map集合的詳解

一,Map

先說一下Map吧~

如果程式中儲存了幾百萬個學生,而且經常需要使用學號來搜尋某個學生,那麼這個需求有效的資料結構就是Map

Map是一種依照鍵(key)儲存元素的容器,鍵(key)很像下標,在List中下標是整數。在Map中鍵(key)可以使任意型別的物件。Map中不能有重複的鍵(Key),每個鍵(key)都有一個對應的值(value)。

一個鍵(key)和它對應的值構成map集合中的一個元素。

Map中的元素是兩個物件,一個物件作為鍵,一個物件作為值。鍵不可以重複,但是值可以重複。

看頂層共性方法找子類特有物件.

Map與Collection在集合框架中屬並列存在

Map儲存的是鍵值對

Map儲存元素使用put方法,Collection使用add方法

Map集合沒有直接取出元素的方法,而是先轉成Set集合,在通過迭代獲取元素

Map集合中鍵要保證唯一性

也就是Collection是單列集合, Map 是雙列集合。

總結: 

Map一次存一對元素, Collection 一次存一個。Map 的鍵不能重複,保證唯一。

Map 一次存入一對元素,是以鍵值對的形式存在.鍵與值存在對映關係.一定要保證鍵的唯一性.

檢視api文件:

interface Map<K,V>

K - 此對映所維護的鍵的型別

V - 對映值的型別

概念

將鍵對映到值的物件。一個對映不能包含重複的鍵;每個鍵最多隻能對映到一個值。

特點

Key和Value是1對1的關係,如:門牌號 :家  老公:老婆

雙列集合

Map學習體系:
 ---| Map  介面    將鍵對映到值的物件。一個對映不能包含重複的鍵;每個鍵最多隻能對映到一個值。
			---| HashMap  採用雜湊表實現,所以無序
            ---| TreeMap   可以對健進行排序

---|Hashtable:
底層是雜湊表資料結構,執行緒是同步的,不可以存入null鍵,null值。
效率較低,被HashMap 替代。
---|HashMap:
底層是雜湊表資料結構,執行緒是不同步的,可以存入null鍵,null值。
要保證鍵的唯一性,需要覆蓋hashCode方法,和equals方法。
---| LinkedHashMap:
該子類基於雜湊表又融入了連結串列。可以Map集合進行增刪提高效率。
---|TreeMap:
底層是二叉樹資料結構。可以對map集合中的鍵進行排序。需要使用Comparable或者Comparator 進行比較排序。return 0,來判斷鍵的唯一性。

常見方法

1、新增:
	1、V put(K key, V value)    (可以相同的key值,但是新增的value值會覆
蓋前面的,返回值是前一個,如果沒有就返回null)                                          
	2、putAll(Map<? extends K,? extends V> m)  從指定對映中將所有對映關
系複製到此對映中(可選操作)。
2、刪除
	1、remove()    刪除關聯物件,指定key物件
	2、clear()     清空集合物件
3、獲取
     1:value get(key); 可以用於判斷鍵是否存在的情況。當指定的鍵不存在的時候,返
回的是null。

3、判斷:
	1、boolean isEmpty()   長度為0返回true否則false
    2、boolean containsKey(Object key)  判斷集合中是否包含指定的key
3、boolean containsValue(Object value)  判斷集合中是否包含指定的value
4、長度:
Int size()

新增:

該案例使用了HashMap,建立了學生姓名和年齡之間的對映關係。並試圖新增重複的鍵。

public class Demo1 {
	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);
		System.out.println(map1);
		// 新增重複的鍵值(值不同),會返回集合中原有(重複鍵)的值,		 System.out.println(map1.put("jack", 30)); //20
		       
		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);
         //
	}
}

刪除:

// 刪除:
		// 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,返回刪除的鍵值對對映的值。
		System.out.println("value:" + map1.remove("java"));
		map1.clear();
		System.out.println("map1:" + map1);

獲取:

// 獲取:
		// 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物件
		// int size() 獲取容器的大小
		System.out.println("value:" + map1.get("jack"));
		System.out.println("map.size:" + map1.size());

判斷:

// 判斷:
		// 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的方式:

1、將map 集合中所有的鍵取出存入set集合。
		Set<K> keySet()   返回所有的key物件的Set集合
                             再通過get方法獲取鍵對應的值。
2、 values() ,獲取所有的值.
		Collection<V> values()不能獲取到key物件
3、 Map.Entry物件  推薦使用   重點
		Set<Map.Entry<k,v>> entrySet()
將map 集合中的鍵值對映關係打包成一個物件
Map.Entry物件通過Map.Entry 物件的getKey,
getValue獲取其鍵和值。

第一種方式:使用keySet

將Map轉成Set集合(keySet()),通過Set迭代器取出Set集合中的每一個元素(Iterator)就是Map集合中的所有的鍵,再通過get方法獲取鍵對應的值。

public class Demo2 {
	public static void main(String[] args) {
		Map<Integer, String> map = new HashMap<Integer, String>();
		map.put(1, "aaaa");
		map.put(2, "bbbb");
		map.put(3, "cccc");
		System.out.println(map);

		//
		// 獲取方法:
		// 第一種方式: 使用keySet
		// 需要分別獲取key和value,沒有面向物件的思想
		// Set<K> keySet() 返回所有的key物件的Set集合

		Set<Integer> ks = map.keySet();
		Iterator<Integer> it = ks.iterator();
		while (it.hasNext()) {
			Integer key = it.next();
			String value = map.get(key);
			System.out.println("key=" + key + " value=" + value);
		}
	}
}

第二種方式:通過values 獲取所有值,不能獲取到key物件

public static void main(String[] args) {
		Map<Integer, String> map = new HashMap<Integer, String>();
		map.put(1, "aaaa");
		map.put(2, "bbbb");
		map.put(3, "cccc");
		System.out.println(map);
// 第二種方式:
		// 通過values 獲取所有值,不能獲取到key物件
		// Collection<V> values()

		Collection<String> vs = map.values();
		Iterator<String> it = vs.iterator();
		while (it.hasNext()) {
			String value = it.next();
			System.out.println(" value=" + value);
		}
}

第三種方式: Map.Entry

public static interface Map.Entry<K,V>

通過Map中的entrySet()方法獲取存放Map.Entry<K,V>物件的Set集合。

Set<Map.Entry<K,V>> entrySet()

面向物件的思想將map集合中的鍵和值對映關係打包為一個物件,就是Map.Entry

,將該物件存入Set集合,Map.Entry是一個物件,那麼該物件具備的getKeygetValue獲得鍵和值。

public static void main(String[] args) {
		Map<Integer, String> map = new HashMap<Integer, String>();
		map.put(1, "aaaa");
		map.put(2, "bbbb");
		map.put(3, "cccc");
		System.out.println(map);
		// 第三種方式: Map.Entry物件 推薦使用 重點
		// Set<Map.Entry<K,V>> entrySet()
		

		// 返回的Map.Entry物件的Set集合 Map.Entry包含了key和value物件
		Set<Map.Entry<Integer, String>> es = map.entrySet();

		Iterator<Map.Entry<Integer, String>> it = es.iterator();

		while (it.hasNext()) {
			
			// 返回的是封裝了key和value物件的Map.Entry物件
			Map.Entry<Integer, String> en = it.next();

			// 獲取Map.Entry物件中封裝的key和value物件
			Integer key = en.getKey();
			String value = en.getValue();

			System.out.println("key=" + key + " value=" + value);
		}
	}

二,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"));

		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 "[email protected]:" + 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 "[email protected]:" + 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的重複健將覆蓋舊鍵,將舊值返回。


相關推薦

Java中的Map集合

一、概述  java中的map集合使用鍵(key)值(value)來儲存資料,其中值(value)可以重複,但鍵(key)必須是唯一,也可以為空,但最多隻能有一個key為空,它的主要實現類有HashM

Map集合,Keyset檢視,Collection 檢視分析

Map集合詳解,Keyset檢視,Collection 檢視分析 map<k,v> k此對映 鍵的型別 v 對映值的型別。 特性:將鍵對映到值的物件。一個對映不能包含重複的鍵;每個鍵最多隻能對映到一個值。 常用方法: clear() : 從此對映中

Java Set集合及Set與List的區別

Java中的Set集合是繼承Collection的介面,是一個不包含重複元素的集合。     下圖是Set集合的原始碼。 Set和List都是以介面都形式來進行宣告。Set主要包含三種存放資料型別都變數,分別是HashSet,LinkedHashSet,TreeSet

Java基礎集合(一)

作為新手,對於集合來講,多少有點感悟 先介紹一下什麼是集合 這是我看的書《java從入門到精通》清華大學出版社 引用裡面的一句話,集合就是一個容器。     對於集合內的各個物件很容易將其存放到集合中,也很容易將其從集合中取出來,還可以按照一定的順序放入。     對集合

Java集合Collection、List、Set、Map使用

Java集合排序及java集合類詳解 (Collection, List, Set, Map) 摘要內容 集合是Java裡面最常用的,也是最重要的一部分。能夠用好集合和理解好集合對於做Java程式的開發擁有無比的好處。本文詳細解釋了關於Java中的集合是如何實現

Java集合--什麼是Map

引言 在很久很久以前,講過Set的實現原理,講到Set就是Map的馬甲,那麼今天我們就來看看Map是如何實現的(本文都基於JDK1.8的版本) 什麼是Map Map和Collection有關的幾個map的關係圖 Map的定義

Java Map集合

一,Map 先說一下Map吧~ 如果程式中儲存了幾百萬個學生,而且經常需要使用學號來搜尋某個學生,那麼這個需求有效的資料結構就是Map。 Map是一種依照鍵(key)儲存元素的容器,鍵(key)很像下標,在List中下標是整數。在Map中鍵(key)可以使任意型別的物件。M

集合Java集合總結(中)-Map家族

接上文,本篇部落格我們接著談論有關集合的內容。 java所有的集合分成三大類。Set類似罐子,把一個物件新增到Set集合時,Set集合無法記住新增這個元素的順序,所以Set裡的元素不能重複。List集合非常想一個數組,可以記住每次新增元素的順序,且List的長

Java中的集合,結合 ArrayList、HashSet 的區別以及HashCode的作用。

Java中的集合:      (1)Collection                           List(有序,可重複)             ArrayList         

java 集合及如何應用

1、結構圖                 2、集合對比說明   有序 允許元素重複 同步 描述

java MapMap.Entry

2018年11月09日 21:14:45 run_666 閱讀數:3 個人分類: 程式設計之坑

JAVA學習篇14——集合

概述: List , Set, Map都是介面,前兩個繼承至Collection介面,Map為獨立介面 Set下有HashSet,LinkedHashSet,TreeSet List下有ArrayList,Vector,LinkedList Map下有Hashta

Java集合

一、陣列和集合的比較 陣列不是面向物件的,存在明顯的缺陷,集合彌補了陣列的缺點,比陣列更靈活更實用,而且不同的集合框架類可適用不同場合。如下: 1:陣列能存放基本資料型別和物件,而集合類存放的都是物件的引用,而非物件本身! 2:陣列容易固定無法動態改變,集合類容量動態改變。

Java集合--什麼是集合

什麼是集合 集合類存放於java.util包中。 集合類存放的都是物件的引用,而非物件本身,出於表達上的便利,我們稱集合中的物件就是指集合中物件的引用(reference)。 集合型別主要有3種:set(集)、list(列表)和map(對映)。 通俗

集合Java集合總結(下)-常用集合類對比

今天我們主要看一張圖。 圖是無意中在網上發現的,個人覺得非常好。(時間久了就忘了出處,請原創原諒~~) 我們還是從左到右分析。 ①所有的類都用到Iterator則說明所有的集合類都有遍歷集合的方法。 ②LinkedList除了繼承AbstractSe

java集合集合面試題目

一、集合與陣列陣列(可以儲存基本資料型別)是用來存現物件的一種容器,但是陣列的長度固定,不適合在物件數量未知的情況下使用。集合(只能儲存物件,物件型別可以不一樣)的長度可變,可在多數情況下使用。二、層次關係如圖所示:圖中,實線邊框的是實現類,折線邊框的是抽象類,而點線邊框的是

Java集合--什麼是Set

簡述 Set和List一樣,也繼承於Collection,是集合的一種。和List不同的是,Set內部實現是基於Map的,所以Set取值時不保證資料和存入的時候順序一致,並且不允許空值,不允許重複值。 然後我們來看下Set的繼承結構 可以看出,

Java程式設計中常用的集合 對你非常有用

Java中的集合概述 集合是一個容器,用來存放引用型別的資料,在java.util包下。 Java中的集合主要有3種類型: List介面: 是一個有序集合,可以放重複的資料。 Set介面: 是一個無序集合,不允許放重複的資料。 Map介面: 是一個無序集合,集合

Java執行緒安全的集合

一、早期執行緒安全的集合 我們先從早期的執行緒安全的集合說起,它們是Vector和HashTable 1.Vector Vector和ArrayList類似,是長度可變的陣列,與ArrayList不同的是,Vector是執行緒安全的,它給幾乎所有的publ

Java集合--什麼是List

簡述 上章簡單介紹了什麼是集合,集合有哪幾種種類。 在這章中我們主要介紹Collection的其中一種實現方式,List。 什麼是List 在上一章,我們已經瞭解了List主要分為3類,ArrayList, LinkedList和Ve