Java集合(7):散列与散列码

       散列的价值在于速度。我们使用数组来保存键的信息,这个信息并不是键本身,而是通过键对象生成一个数字(散列码),作为数组下标。由于数组的容量是固定的,而散列容器的大小是可变的,所以不同的键可以产生相同的数组下标(散列码)。也就是说,可能会有冲突(当然也有特例,比如EnumMap和EnumSet)。所以,数组的值存放着一个保存所有相同散列码的值的list(引用)。然后对list中的值使用equals进行线性查询。如果散列函数设计的比较好的话,数组的每个位置只有较少的值,并且浪费空间也小。于是,查询过程就是首先计算键的散列码得到数组下标,然后内存寻址(时间复杂度为O(1),赋值)找到数组的值,再遍历list(时间复杂度为O(n),线性查询)即可。即hashCode和equals共同确定了对象的唯一性。

       所有类都继承于Object。Object的hashCode方法生成的散列码,实际上是默认使用对象的地址计算散列码;而Object的equals方法实际上就是地址比较(==)。显然,当我们在使用散列容器(如HashMap的Key,HashSet等)时,我们自定义的类中还继承Object的hashCode和equals是不行的。必须重写hashCode和equals方法。好的hashCode()应该产生分布均匀的散列码。可以用IDE自动生成。下面是一个例子:

 1 import java.util.List;
 2 
 3 public class Test9 {
 4 
 5     boolean a;
 6     byte b;
 7     short c;
 8     int d;
 9     char e;
10     long f;
11     float g;
12     double h;
13     String i;
14     List<String> j;
15     int[] k;
16 
17     @Override
18     public int hashCode() {
19         // [STEP1] hashCode()里的魔法数字,之所以选择31,是因为它是个奇素数,如果乘数是偶数,并且乘法溢出的话,信息就会丢失,因为与2相乘等价于移位运算。
20         // 使用素数的好处并不是很明显,但是习惯上都使用素数来计算散列结果。31有个很好的特性,就是用移位和减法来代替乘法,可以得到更好的性能:31*i==(i<<5)-i。现在的VM可以自动完成这种优化。(from 《Effective Java》)
21         final int prime = 31;
22         // [STEP2] 为对象中每个有意义的域用下面公式计算散列码 result = prime * result + c
23         int result = 1;
24         // boolean
25         result = prime * result + (a ? 1231 : 1237);
26         // byte/short/int/char
27         result = prime * result + b;
28         result = prime * result + c;
29         result = prime * result + d;
30         result = prime * result + e;
31         // long
32         result = prime * result + (int) (f ^ (f >>> 32));
33         // float
34         result = prime * result + Float.floatToIntBits(g);
35         // double
36         long temp;
37         temp = Double.doubleToLongBits(h);
38         result = prime * result + (int) (temp ^ (temp >>> 32));
39         // 对象
40         result = prime * result + ((i == null) ? 0 : i.hashCode());
41         // List(要求每个元素实现hashCode)
42         result = prime * result + ((j == null) ? 0 : j.hashCode());
43         // 数组(要求每个元素实现hashCode)
44         result = prime * result + Arrays.hashCode(k);
45         // [STEP3] 返回
46         return result;
47     }
48     @Override
49     public boolean equals(Object obj) {
50         if (this == obj)
51             return true;
52         if (obj == null)
53             return false;
54         if (getClass() != obj.getClass())
55             return false;
56         Test9 other = (Test9) obj;
57         if (a != other.a)
58             return false;
59         if (b != other.b)
60             return false;
61         if (c != other.c)
62             return false;
63         if (d != other.d)
64             return false;
65         if (e != other.e)
66             return false;
67         if (f != other.f)
68             return false;
69         if (Float.floatToIntBits(g) != Float.floatToIntBits(other.g))
70             return false;
71         if (Double.doubleToLongBits(h) != Double.doubleToLongBits(other.h))
72             return false;
73         if (i == null) {
74             if (other.i != null)
75                 return false;
76         } else if (!i.equals(other.i))
77             return false;
78         if (j == null) {
79             if (other.j != null)
80                 return false;
81         } else if (!j.equals(other.j))
82             return false;
83         if (!Arrays.equals(k, other.k))
84             return false;
85         return true;
86     }
87 }

 

转载于:https://www.cnblogs.com/storml/p/8550463.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

301转向代码合集

教育资源网将SEO工作中所需要的301转向代码进行了整理&#xff0c;收藏并分享&#xff0c;以备查阅。 1、IIS下301设置 Internet信息服务管理器 -> 虚拟目录 -> 重定向到URL&#xff0c;输入需要转向的目标URL&#xff0c;并选择“资源的永久重定向”。 2、ASP下的301转向…

TQ210——核心板和底板

TQ210——核心板和底板 1、TQ210简介【TQ210_COREB核心板 TQ210_BOARD_V4底板】 三星Cortex-A8 S5PV210芯片&#xff0c;运行最大频率1GHZ&#xff0c;处理器内部为64/32位总线结构&#xff0c;32/32KB一级缓存&#xff0c;512KB二级缓存。自带3D加速引擎&#xff08;SGX540&a…

“华为天才少年”自制百大Up奖杯,网友:技术难度不高侮辱性极强

来源&#xff1a;雷锋网B站硬核黑科技Up主、AI算法工程师稚晖君&#xff0c;停更了好一阵子后&#xff0c;这位自称野生钢铁侠的超硬核Up主终于又发布了新作品。之所以停更这么久&#xff0c;Up主解释说&#xff0c;不是因为在野外被捕了&#xff0c;纯粹是因为工作太忙了。熟悉…

CListBox的函数

CListBox::GetCurSel 函数原型&#xff1a; int GetCursel( ) const; 返回值&#xff1a; 从当前选中的项的索引为零开始。如果没有项目被当前选定或如果列表框是一个多次选择列表框&#xff0c;则返回LB_ERR。 说明&#xff1a; 从当前选中的项的索引为零开始,如果任何的,在…

终极教程,带具体实验现象,1个GPIO控制2个LED显示4种状态,欢迎讨论!

芯片之家前几天发了一篇文章&#xff0c;讨论1个GPIO控制2个LED显示4种状态&#xff0c;并没有带具体的实验现象&#xff0c;有点小遗憾&#xff1a;绝妙&#xff01;1个GPIO控制2个LED显示4种状态&#xff0c;什么&#xff1f;你不信&#xff1f;&#xff08;点击阅读&#xf…

【转载】AE表达式中英文对照

全局对象 Comp comp(name) 用另一个名字给合成命名。 Footage footage(name) 用另一个名字给脚本标志命名。 Comp thisComp 描述合成内容的表达式。例如&#xff1a;thisComp.layer(2) Layer, Light, or Camera thisLayer 是对层本身的描述&#xff0c;thisLayer是一个默认的对…

《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #15 ramzswap

HACK #15 ramzswap 本节介绍将一部分内存作为交换设备使用的ramzswap。ramzswap是将一部分内存空间作为交换设备使用的基于RAM的块设备。对要换出&#xff08;swapout&#xff09;的页面进行压缩后&#xff0c;不是写入磁盘&#xff0c;而是写入内存。可以使用的内存仅为完成压…

TQ210——底板部分原理图

TQ210——底板部分原理图 1、主电源接口&#xff08;过压过流保护&#xff09; 2、串行接口 2路5线RS232电平的DB9接口&#xff0c;4路TTLT电平扩展接口 COM1和PC之间通信需使用直连串口线 COM2和PC通信需使用交叉串口线 接口UART2可接GPRS模块实现打电话发短信功能&#xff1b…

DebugOutputString 使用

https://blog.csdn.net/wolfinrain/article/details/2444040

有趣的灵魂百里挑一,Linux同学你低下头干嘛,起来说下这个问题。

今天我们不讲源码&#xff0c;不说面试题&#xff0c;我们来说点轻松的&#xff0c;聊点好玩的&#xff0c;我们来看看linux下有哪些酷酷的&#xff0c;有意思的命令。0x00 sl - 呜呜&#xff0c;让开&#xff0c;小火车来啦0x01 cowsay - 一起来 say hello0x02 cmatrix - 超级…

北电PBX资料_LD 24 進線直撥功能設定

LD 24 進線直撥功能設定 程式提示 輸入指令符號 說 明 備 註 REQ NEW 新建 CHG 修改 OUT 刪除 END 結束 PRT 查看 TYPE DIS DISA CUST 0 第 0 客戶群 SPWD (不顯示) 輸入 1234 DN DISA 之代號(不可與其它編碼衝突) AUTR (NO)/YES NO - 系統不代輸入功能碼 YES- 撥號者可直按特權…

nodejs在cmd提示不是内部或外部命令解决方法

今天用cmd安装个库,结果发现node不是内部命令,于是搜索了下解决方法,解决方法是&#xff1a; . 找到变量值中node的安装地址,比如C:develop\nodejs,如果不是这个地址改成现在新的安装的地址,然后保存,重新打开cmd,输入 node -v 查看版本号,就会发现一切正常啦!当然这只针对于安…

TQ210——常见问题

TQ210——常见问题 1、TQ210板子使用几V供电&#xff0c;接几寸屏&#xff0c;哪种屏&#xff1f; TQ210 V3版使用的是12V1A的稳定电源&#xff0c;TQ210V4版使用的是5V2A的稳定电源&#xff0c;两个版本都可以使用7寸TN92型号的电容屏或者电阻屏&#xff0c;使用的时候在LCD…

float型数据与字节数组的转化

https://blog.csdn.net/sygdp21/article/details/20476697

用mtrace定位内存泄漏

一. 缘起有的公众号读者&#xff0c;看完我上次写给大学生的查bug方法后&#xff0c;希望我多分享一些查bug的实践经验和具体步骤&#xff0c;比如如何查内存泄漏和core dump问题。所以&#xff0c;就打算写这篇文章。二. 内存泄漏简介内存泄漏&#xff0c;是一个谈虎色变的问题…

为什么每个人都应该尝试Ubuntu下篇 Why Everyone Should Try Ubuntu 分享

但是老实说&#xff0c;我认为 Ubuntu 拥有长期的生存能力重要于其短期的实用主义。最近几年来&#xff0c;对于改进 Linux 桌面方面&#xff0c;Ubuntu 做得比其他发行版本要多。这就是我已详细讨论的&#xff0c;其带来的实际好处&#xff0c;但它也有许多不明确的地方。感谢…

陪我长大的村,镇,学校和家乡

我们村在广西河池市金城江区九圩镇江潭村山岳屯上面的字可以省略&#xff0c;因为看起来确实麻烦。地图上是这样显示的。小说我们村的那座桥&#xff0c;那座老桥据说是我爷爷那一辈人建起来的&#xff0c;用的是实打实的大石头。我上小学那段那会&#xff0c;我们同龄的小孩都…

Linux硬盘分区

MBR分区主分区&#xff1a;14&#xff0c;一块硬盘最多4个主分区&#xff0c;对主机必须有&#xff0c;主分区可以格式化ntfs&#xff0c;存数据。扩展分区&#xff1a;14&#xff0c;一块硬盘最多一个扩展分区&#xff0c;可以没有扩展分区&#xff0c;可以划分成更小的单元&a…

使用FileZilla Server轻松搭建个人FTP服务器

使用FileZilla Server轻松搭建个人FTP服务器 添加一个用户&#xff0c;然后在“共享文件夹”下设置将要设为FTP目录的文件夹和操作权限&#xff0c;点击确定 https://jingyan.baidu.com/article/ed15cb1bb6de421be3698188.html 可以为不同的用户创建不同的目录&#xff0c;新建…

TQ210——启动方式

TQ210——启动方式