1. 程式人生 > >Java Map 怎樣實現Key 的唯一性?

Java Map 怎樣實現Key 的唯一性?

存儲 new sha iterator int -m pareto center key

大家都知道。在Map和Set不可存在反復元素?

可是對於內部的細節我們並不了解。今天我們就一塊來 探討一下!


1 對於 HashMap HashSet

他們的底層數據結構的實現是:維護了一張 HashTable 。容器中的元素所有存儲在Hashtable 中。他們再加入元素的時候,是怎樣推斷是否存在有反復元素的呢? 每個被加入的元素都有一個 hashCode(哈希值),他們先比較哈希值,是否同樣? 不同樣的元素,加入進入 HashTable. 假設hashCode同樣的話, 再去比較 equals()方法,假設也同樣的話,JVM就覺得數據已經存在了。就不會加入數據!


如圖1:

技術分享


2 對於 TreeMap TreeSet

他們底層是數據結構的實現是:維護了一棵二叉樹。 容器中加入元素的時候,他們有是怎麽推斷是否有同樣元素的?我們都直到 TreeMap TreeSet 她們 都是 有序的存儲數據。

為了維護 數據的唯一性。 再存入數據的時候,他們會調用元素中 實現的 Comparable 的 compareTo() 方法(代碼1)。 或者 集合本身創建的時候 傳入了 叠代器(代碼2). 詳細的實現是:調用比較方法,返回-1 的時候,加入到左子樹,返回1 的時候 加入到 右子樹。

返回0 有同樣數據 不加入該元素!


如圖2

技術分享


代碼1;(原理一)

package stu.love.v;

import java.util.*;
//什麽時候用Map
/*
當存在映射關系時。
每一個學員都相應一個地址
姓名,年齡同樣的視為同一個人

*/
// 容器中的對象 本身 具備比較性。

class StudentD implements Comparable<StudentD>
{
	private String name;
	private int age;
	
	public StudentD(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	
	public int compareTo(StudentD stu)
	{
		int t = this.age-stu.age;
		return t==0?

this.name.compareTo(stu.name):t; } // 重寫了 hashCode 方法 public int hashCode() { return name.hashCode()+age*36; } // 重寫了 equals 方法 public boolean equals(Object obj) { if(!(obj instanceof StudentD)) throw new ClassCastException("類型異常"); StudentD stu =(StudentD)obj; return this.name.equals(stu.name) && this.age ==stu.age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return this.name; } public int getAge() { return this.age; } public String toString() { return this.name +","+age; } } class Demo16 { public static void main(String[] args) { //保證鍵唯一的原理,先推斷哈希值是否同樣,同樣再推斷equals() HashMap<StudentD,String> hm = new HashMap<StudentD,String>(); hm.put(new StudentD("xiaobai",23),"shanghai"); hm.put(new StudentD("wanghei",20),"beijing"); hm.put(new StudentD("lisi",28),"shenzhen"); hm.put(new StudentD("lisi",28),"shenzhen"); // Map 第一種 叠代方式 依據 key 找 value Set<StudentD> set=hm.keySet(); for(Iterator<StudentD> ite = set.iterator();ite.hasNext();) { StudentD stu = ite.next(); String value = hm.get(stu); sop(stu+"的地址是:"+value); } // map 的 另外一種 叠代方式 獲取 鍵值對。entry 獲取當中的 key 和 value Set<Map.Entry<StudentD,String>> entry = hm.entrySet(); for(Iterator<Map.Entry<StudentD,String>> ite = entry.iterator();ite.hasNext();) { Map.Entry<StudentD,String> kv = ite.next(); StudentD key = kv.getKey(); String value = kv.getValue(); sop(key+"的地址是:"+value); } } public static void sop(Object obj) { System.out.println(obj); } }




代碼2:

package stu.love.v;

/*
TreeMap:
HashMap保證鍵唯一的原理和HashSet同樣
TreeMap保證鍵唯一的原理和TreeSet同樣

*/
import java.util.*;


class Student1
{
	private String name;
	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;
	}


	private int age;
	
	public Student1(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	
	
	public String toString()
	{
		return name+","+age;
	}
	
}



//  比較器
class CompareByName implements Comparator<Student1>
{
	public int compare(Student1 s1,Student1 s2)
	{
//		這樣寫的方法 很好!

簡潔 int t = s1.getName().compareTo(s2.getName()); return t ==0?s1.getAge()-s2.getAge():t; } } class Demo17 { public static void main(String[] args) { // 原理二: //保證鍵唯一的原理:比較方法的返回值為0 TreeMap<Student1,String> tm = new TreeMap<Student1,String>(new CompareByName()); tm.put(new Student1("xiaobai",23),"shanghai"); tm.put(new Student1("wanghei",20),"beijing"); tm.put(new Student1("lisi",28),"shenzhen"); tm.put(new Student1("lisi",28),"shenzhen"); Set<Map.Entry<Student1,String>> entry = tm.entrySet(); for(Iterator<Map.Entry<Student1,String>> it = entry.iterator();it.hasNext();) { Map.Entry<Student1,String> kv = it.next(); Student1 key = kv.getKey(); String value = kv.getValue(); sop(key+"的地址是:"+value); } } public static void sop(Object obj) { System.out.println(obj); } }





Java Map 怎樣實現Key 的唯一性?