参考的优秀文章:

《Java编程思想》第四版

《Effective Java》第二版

Map接口是映射表的结构,维护键对象与值对象的对应关系,称键值对。

> hashcode()和equals()

hashcode()和equals()即用于识别对象的身份。

在HashMap或类似的实现中,查找一个对象,是通过hashcode()返回的散列值映射到一个范围内的下标,在通过equals()比较此下标连接的链表是否存在相同的对象。

简单来说,hashcode()用于参考、快速定位(缩减范围),真正是否等于是依赖equals()。

默认的hashcode()和equals()

如何对象没有覆盖这两个方法,那么就是继承Object对象的。

在Object中,hashcode()是使用对象的地址计算散列值;equals()只比较对象的地址。

必要的时候,我们需要覆盖这两个方法。

覆盖这两个方法有什么原则呢?

equals()的覆盖,主要是基于此对象的业务。

而hashcode()的覆盖原则,详情可参见《Effective Java》的“覆盖equals时总要覆盖hashcode”一节。

有几个比较重要的原则:

1、两个equals相等的对象,其hashcode是相等的。

2、两个equals不等的对象,其hashcode有可能是相等的。

3、好的hashcode()应产生分布均匀的散列码。

基于第3点,《Effective Java》有具体的建议。

1、定义变量result为非零的数。

2、用公式result = 31 * result + c,其中c是类中各个域的散列值。

用Eclipse生成的hashcode()与此原则类似,我们可以看看:

public class User {

    private Integer id;
private String name;
private boolean flag = false;
private long phoneNumber; @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (flag ? 1231 : 1237);
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + (int) (phoneNumber ^ (phoneNumber >>> 32));
return result;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (flag != other.flag)
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (phoneNumber != other.phoneNumber)
return false;
return true;
} }

> 常用的Map实现

Map接口有几个常用的实现类,HashMap、TreeMap、LinkedHashMap、ConcurrentHashMap。其中HashMap最常用。

HashMap,基于散列表实现,查找速度快(依赖hashcode()和equals()),存放元素无序。

TreeMap,基于红黑树实现,存放有序(依赖Compareable)。

LinkedHashMap,基于散列表、双向链表实现。如HashMap的查找速度,遍历时有序(默认为插入顺序,可通过构造方法设置“最近最少使用(Least Recently Used)顺序”)。

ConcurrentHashMap,线程安全的HashMap,用于替代HashTable(线程安全,但基于整个对象的锁实现的,效率不高),而ConcurrentHashMap是采用分段加锁的方式实现,提升了效率。

代码演示LinkedHashMap的两种排序:

import java.util.LinkedHashMap;
import java.util.Map; public class LinkedHashMapTester { public static void main(String[] args) { System.out.println("LinkedHashMap 根据插入顺序排列:");
Map<String, String> map = new LinkedHashMap<String, String>();
for (Integer i = 0; i < 5; i++) {
map.put("k" + i.toString(), "v" + i.toString());
} for (Integer i = 10; i > 5; i--) {
map.put("k" + i.toString(), "v" + i.toString());
} System.out.println(map);
map.get("k10");
System.out.println(map); System.out.println("LinkedHashMap 根据最近最少使用(Least Recently Used)顺序排列:");
map = new LinkedHashMap<String, String>(16, 0.75f, true); // 没有了其他构造方法设置其排序为true了。初始容量、加载因子使用默认的16和0.75。
for (Integer i = 0; i < 5; i++) {
map.put("k" + i.toString(), "v" + i.toString());
} for (Integer i = 10; i > 5; i--) {
map.put("k" + i.toString(), "v" + i.toString());
} System.out.println(map);
map.get("k10");
System.out.println(map);
} }

日志,注意看使用“K10”后“K10”的位置:

LinkedHashMap 根据插入顺序排列:
{k0=v0, k1=v1, k2=v2, k3=v3, k4=v4, k10=v10, k9=v9, k8=v8, k7=v7, k6=v6}
{k0=v0, k1=v1, k2=v2, k3=v3, k4=v4, k10=v10, k9=v9, k8=v8, k7=v7, k6=v6}
LinkedHashMap 根据最近最少使用(Least Recently Used)顺序排列:
{k0=v0, k1=v1, k2=v2, k3=v3, k4=v4, k10=v10, k9=v9, k8=v8, k7=v7, k6=v6}
{k0=v0, k1=v1, k2=v2, k3=v3, k4=v4, k9=v9, k8=v8, k7=v7, k6=v6, k10=v10}

【Java】Map杂谈,hashcode()、equals()、HashMap、TreeMap、LinkedHashMap、ConcurrentHashMap的更多相关文章

  1. java:Map借口及其子类HashMap四

    java:Map借口及其子类HashMap四 使用非系统对象作为key,使用匿名对象获取数据 在Map中可以使用匿名对象找到一个key对应的value. person: public class Ha ...

  2. java:Map借口及其子类HashMap五,identityHashMap子类

    java:Map借口及其子类HashMap五,identityHashMap子类 了解:identityHashMap子类 一般情况下,标准的Map,是不会有重复的key值得value的,相同的key ...

  3. java:Map借口及其子类HashMap二

    java:Map借口及其子类HashMap二 重点:所有的集合必须依赖Iterator输出 Map<String, Integer> map = new HashMap<String ...

  4. 【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解

    今天来介绍一下容器类中的另一个哈希表———>LinkedHashMap.这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap的全部特性,并青出于蓝而胜于蓝,有着一 ...

  5. Java集合详解6:TreeMap和红黑树

    Java集合详解6:TreeMap和红黑树 初识TreeMap 之前的文章讲解了两种Map,分别是HashMap与LinkedHashMap,它们保证了以O(1)的时间复杂度进行增.删.改.查,从存储 ...

  6. Java 数据类型:集合接口Map:HashTable;HashMap;IdentityHashMap;LinkedHashMap;Properties类读取配置文件;SortedMap接口和TreeMap实现类:【线程安全的ConcurrentHashMap】

    Map集合java.util.Map Map用于保存具有映射关系的数据,因此Map集合里保存着两个值,一个是用于保存Map里的key,另外一组值用于保存Map里的value.key和value都可以是 ...

  7. 接口java.util.Map的四个实现类HashMap Hashtable LinkedHashMap TreeMap

    java中HashMap,LinkedHashMap,TreeMap,HashTable的区别 :java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMa ...

  8. Map,Hashmap,LinkedHashMap,Hashtable,TreeMap

    java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap. Map主要用于存储健值对, ...

  9. JAVA基础学习-集合三-Map、HashMap,TreeMap与常用API

    森林森 一份耕耘,一份收获 博客园 首页 新随笔 联系 管理 订阅 随笔- 397  文章- 0  评论- 78  JAVA基础学习day16--集合三-Map.HashMap,TreeMap与常用A ...

随机推荐

  1. JavaOOP项目 CMS内容管理系统

    数据库里创建一个News表,要有标题.作者.时间.内容等列. 1:首先要使用JDBC进行数据库连接,得先在项目里新建一个Folder,把Sqlserver 的驱动jar包导入. 2:使用MyEclip ...

  2. SPOJ COT2 Count on a tree II(树上莫队)

    题目链接:http://www.spoj.com/problems/COT2/ You are given a tree with N nodes.The tree nodes are numbere ...

  3. linux centos5.7(32bit) oracle 10g oracle11g

    cenOS5.5安装oracle10g(傻瓜篇) http://www.cnblogs.com/fnng/archive/2012/06/19/2554159.html  (转) 在cenOS5.5上 ...

  4. paper 9:SVM番外篇:支持向量机系列六:Duality —— 关于 dual 问题推导的一些补充理论。

    在之前关于 support vector 的推导中,我们提到了 dual ,这里再来补充一点相关的知识.这套理论不仅适用于 SVM 的优化问题,而是对于所有带约束的优化问题都适用的,是优化理论中的一个 ...

  5. sql 中延迟执行

    SQL有定时执行的语句WaitFor. 语法格式:waitfor {delay 'time'|time 'time'} delay后面的时间是需要延迟多长时间后执行. time后面的时间是指定何时执行 ...

  6. 夺命雷公狗ThinkPHP项目之----企业网站30之网站前台头部导航的高亮显示

    我们这个其实也是最简单的一个,首页高亮,那么我们需要先在中间层里面定义一个index = false: 然后在首页控制器里面定义一个 index = true 最后一步就是 在首页的模版上给一个判断: ...

  7. JSP-03-实现数据传递

    会话跟踪:隐藏表单域.URL重写和Cookie 3.1 传参方法 get /post 区别   3.2  request 获取参数 数据类型  变量名  =  (数据类型)request.getPar ...

  8. MYSQL 、Oracle、SQLServer 数据库中时间的格式化输出

    在MYSQL 中格式化输出 date_forma t(date,'yyyyMMddHHmmss') Oracle 中格式化输出 to_char(time ,'yyyyMMddHHmmss') SQL ...

  9. Hadoop之TaskInputOutputContext类

    在MapReduce过程中,每一个Job都会被分成若干个task,然后再进行处理.那么Hadoop是怎么将Job分成若干个task,并对其进行跟踪处理的呢?今天我们来看一个*Context类——Tas ...

  10. Java如何对ArrayList里的元素排序