Java Map 怎样实现Key 的唯一性?
大家都知道。在Map和Set不可存在反复元素?
可是对于内部的细节我们并不了解。今天我们就一块来 探讨一下!
1 对于 HashMap HashSet
他们的底层数据结构的实现是:维护了一张 HashTable 。容器中的元素所有存储在Hashtable 中。他们再加入元素的时候,是怎样推断是否存在有反复元素的呢? 每个被加入的元素都有一个 hashCode(哈希值),他们先比較哈希值,是否同样? 不同样的元素,加入进入 HashTable. 假设hashCode同样的话, 再去比較 equals()方法,假设也同样的话,JVM就觉得数据已经存在了。就不会加入数据!
如图1:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbG92ZV9KYXZjX3lvdQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
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 的唯一性?的更多相关文章
- Java Map集合按照key和value排序之法
一.理论基点 Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等. TreeMap:基于红黑树(Red-Black-Tre ...
- java map遍历、排序,根据value获取key
Map 四种遍历: Map<String,String> map = new HashMap<String, String>(); map.put("one" ...
- Java Map获取key和value 以及String字符串转List方法
一.问题描述 这里描述两个问题: 1.Java Map获取key和value的方法: 2.String字符串转List的方法: 二.解决方法 1.Java Map获取key和value的方法 2. ...
- [Android] View.setTag(key,Object) (java.lang.IllegalArgumentException: The key must be an application-specific resource id.)
转自: http://blog.csdn.net/brokge/article/details/8536906 setTag是android的view类中很有用的一个方法,可以用它来给空间附加一些信息 ...
- java Map实现的cache manager
一个模仿memcached的JAVA虚拟缓存工具,可以缓存java对象 import java.io.ByteArrayInputStream; import java.io.ByteArrayOut ...
- Java map 详解 - 用法、遍历、排序、常用API等
尊重原创: http://www.cnblogs.com/lzq198754/p/5780165.html 概要: java.util 中的集合类包含 Java 中某些最常用的类.最常用的集合类是 L ...
- Java Map用法
Map简介 将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值.此接口取代 Dictionary类,后者完全是一个抽象类,而不是一个接口. Map 接口提供三种collectio ...
- Java Map 及相应的一些操作总结
Map是我们在开发的时候经常会用到的,大致有以下几个操作,其中putAll方法是针对集合而言的操作,故不再进行说明,下面请看一下常用的知识点吧,尤其是keySet和Values两个方法及相应值的获取方 ...
- Java Map 集合实现类
Map 用于保存具有映射关系的数据,集合里会保存两组值,一组用于保存Map里的key,一组用于保存Map里的value,key与map可以是任何引用类型数据.Map的key不允许重复.key与valu ...
随机推荐
- Objective-C设计模式——单例Singleton(对象创建)
单例 和其它语言的单例产不多,可以说是最简单的一种设计模式了.但是有几个点需要注意下,单例就是一个类只有一个实例. 所以我们要想办法阻止该类产生别的实例,一般语言中都会将构造函数写为private.但 ...
- cideogniter部署到阿里云服务器出现session加载错误
A PHP Error was encounteredSeverity: WarningMessage: mkdir() [function.mkdir]: Invalid argumentFilen ...
- Spring框架之控制反转和依赖注入
学Spring框架必须理解控制反转和依赖注入.下面各自举一个例子,来说明控制反转和依赖注入. IOC(控制反转):应用本身创建和维护的依赖对象:现在交由外部容器(Spring)来创建和维护:这个控制权 ...
- sublime text3 =个人插件
1.sublime text3汉化插件安装. ctrl+shift+p → Package Control:Install Package → ChineseLocalization preferen ...
- PHPStorm+XDebug进行调试
笔者的开发环境如下: Windows8.1+Apache+PhpStorm+XDebug+Firefox(XDebug helper 1.4.3插件). 一.XDebug安装配置 (1)下载XDebu ...
- HDU_1207_汉诺塔2
汉诺塔II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- 梦想CAD控件 2018.10.15更新
下载地址: http://www.mxdraw.com/ndetail_10105.html 1. 完善com接口的ToCurves函数,转换CAD文字,多行文字到曲线 2. 修改DrawImage接 ...
- Ubuntu搭建LAMP开发环境
1.安装Apache sudo apt-get install apache2 测试: 浏览器访问 (如:http://localhost),出现It Works!网页. 查看状态: service ...
- oracle关闭
Alert log 要每天查看 abort 关闭冷备会无法使用
- wpf 自定义单选按钮 RadioButton
新建RadioButtonEx.cs public class RadioButtonEx : RadioButton { public Geometry SelectIcon { get { ret ...