【Java】Map杂谈,hashcode()、equals()、HashMap、TreeMap、LinkedHashMap、ConcurrentHashMap
参考的优秀文章:
《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的更多相关文章
- java:Map借口及其子类HashMap四
java:Map借口及其子类HashMap四 使用非系统对象作为key,使用匿名对象获取数据 在Map中可以使用匿名对象找到一个key对应的value. person: public class Ha ...
- java:Map借口及其子类HashMap五,identityHashMap子类
java:Map借口及其子类HashMap五,identityHashMap子类 了解:identityHashMap子类 一般情况下,标准的Map,是不会有重复的key值得value的,相同的key ...
- java:Map借口及其子类HashMap二
java:Map借口及其子类HashMap二 重点:所有的集合必须依赖Iterator输出 Map<String, Integer> map = new HashMap<String ...
- 【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解
今天来介绍一下容器类中的另一个哈希表———>LinkedHashMap.这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap的全部特性,并青出于蓝而胜于蓝,有着一 ...
- Java集合详解6:TreeMap和红黑树
Java集合详解6:TreeMap和红黑树 初识TreeMap 之前的文章讲解了两种Map,分别是HashMap与LinkedHashMap,它们保证了以O(1)的时间复杂度进行增.删.改.查,从存储 ...
- Java 数据类型:集合接口Map:HashTable;HashMap;IdentityHashMap;LinkedHashMap;Properties类读取配置文件;SortedMap接口和TreeMap实现类:【线程安全的ConcurrentHashMap】
Map集合java.util.Map Map用于保存具有映射关系的数据,因此Map集合里保存着两个值,一个是用于保存Map里的key,另外一组值用于保存Map里的value.key和value都可以是 ...
- 接口java.util.Map的四个实现类HashMap Hashtable LinkedHashMap TreeMap
java中HashMap,LinkedHashMap,TreeMap,HashTable的区别 :java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMa ...
- Map,Hashmap,LinkedHashMap,Hashtable,TreeMap
java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap. Map主要用于存储健值对, ...
- JAVA基础学习-集合三-Map、HashMap,TreeMap与常用API
森林森 一份耕耘,一份收获 博客园 首页 新随笔 联系 管理 订阅 随笔- 397 文章- 0 评论- 78 JAVA基础学习day16--集合三-Map.HashMap,TreeMap与常用A ...
随机推荐
- 构造方法特点,void
构造方法特点: 1.和类有相同的名字 2.无返回值 3.被默认强制void void作用:====>>说明声明的方法没有返回值 构造方法作用: -->初始化实例属性 -->用于 ...
- register_shutdown_function
脚本时常死掉,而且并不总是那么好看. 我们可不想给用户显示一个致命错误,又或者一个空白页(在display_errors设为off的情况下) . PHP中有一个叫做 register_shutdow ...
- asp上传图片提示 ADODB.Stream 错误 '800a0bbc'的解决方法
asp上传图片提示 ADODB.Stream 错误 '800a0bbc' 有这个提示有很多问题导致.权限是常见一种.这个不多说,还有一个有点怪的就是 windows2008显示系统时间的格式竟然是:2 ...
- bash广播
terminal1$: mkfifo script_name terminal2$: cat script_name terminal1$: script -f script_name 可以发广播到t ...
- mongodb版本管理
使用gradle. 查找最新版本http://mvnrepository.org/ compile "org.mongeez:mongeez:0.9.6" 配置spring < ...
- [Ubuntu] Ubuntu搭建VPN服务器pptpd
在 Ubuntu 上搭建 VPN 服务器的方法非常多,比较著名的有 PPTP, L2TP/IPSec 和 OpenVPN. 这三种方式中后两者的安全性比较好,但配置较麻烦.其中 OpenVPN 在 W ...
- zw版【转发·台湾nvp系列Delphi例程】HALCON HighpassImage
zw版[转发·台湾nvp系列Delphi例程]HALCON HighpassImage unit Unit1;interfaceuses Windows, Messages, SysUtils, Va ...
- 【海岛帝国系列赛】No.4 海岛帝国:LYF的太空运输站
50212228海岛帝国:LYF的太空运输站 [试题描述] 最近,“购物券”WHT在“药师傅”帝国资源大会上提出了“SSTS”太空运输站计划.由于恐怖分子前些日子刚猖狂完,炸毁高楼无数,YSF不得不执 ...
- Mac OX 隐藏文件夹,文件,应用,磁盘的2种方法 hide finder folder, file, application, volume in 2 ways
经常需要主目录下隐藏一些文件夹之类的, 第一想到的当然就是:在要隐藏的文件夹前面加『.』(leading dot),这个用法当然可以的了 用习惯了Linux/GNU系统的,基本习惯使用这种办法 但是, ...
- FTP上传类
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;usi ...