涨知识:equals 和 == 你真的了解吗?
基本概念
- ==是运算符,比较的是两个变量是否相等;
- equals()是Object方法,用于比较两个对象是否相等
看一下源码:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
当this==anObject的时候,返回true,即this 和 obj引用同一个对象时,才会返回true;
还有就是当判断字符串相等的时候,当anObject是String类型,并且长度和内容一样的时候,返回true;
小结
只有当引用一个对象的时候,才会返回true。
而我们在实际用equals()方法的时候,我们往往不是为了判断两个引用的是一个对象,因此我们此时要重写equals()方法;
equals()有以下的公约必须遵守:
- 对称性:x,y非空,如果x.equals(y)返回true,那么y.equals(x)必为true;
- 自反性:对于任何非null的引用值x,x.equals(x)必须返回true;
- 传递性:x,y,z非空,x.equals(y),y.equals(z)返回true,那么x.equals(z)必为true;
- 一致性:x,y非空,只要对象信息没有被修改,那么多次调用x.equals(y)的结果肯定都一样;
- 对于任何非null的引用值x,x.equals(null)必须返回false;
因此,我们一般有以下推论:
- 任何情况下,x.equals(null),永远返回是false;x.equals(和x不同类型的对象)永远返回是false。
- equals()相等的两个对象,hashcode()一定相等;反过来:hashcode()不等,一定能推出equals()也不等;
- hashcode()相等,equals()可能相等,也可能不等
现在我们可以这样解释了:
1、因为是按照hashCode来访问小内存块,所以hashCode必须相等。
2、HashMap获取一个对象是比较key的hashCode相等和equal为true。
3、比如对象ObjectA和ObjectB他们都有属性name,那么hashCode都以name计算,所以hashCode一样,但是两个对象属于不同类型,所以equal为false。所以hashCode相等,却可以equal不等
当我们编写完成了equals()方法的时候,我们要问自己三个问题:它是否是对称的、传递的、一致的;
问题:重写equals()方法的时候总要重写hashcode()方法,为什么要重载equal方法?
在每个重写equals()的类中,我们必须重写hashcode()方法;如果不这样做,会违反hashcode()的公约:
- 1.只要对象的信息没有改变,那么对一个对象调用多次,hashcode()方法都必须始终如一的返回同一个整数;
- 2.如果两个对象根据equals()方法比较是相等的,那么调用这两个对象中任意一个对象的hashcode()方法都必须产生同样的结果;
- 3.如果两个对象根据equals()方法比较是不相等的,那么调用这两个对象中任意一个对象的hashcode()方法不一定产生同样的结果;
相等的对象必须有相同的散列码
代码示例
import java.util.HashSet;
import java.util.Set; /**
* hashcode和equals方法
* HashMap中有一个put方法,put(key,value)key是无序不可重复的
*/
public class SetTest2 {
public static void main(String[] args)
{
//创建集合
Set es = new HashSet(); Employee e1 = new Employee("1000","tao");
Employee e2 = new Employee("1000","tao");
// Employee e2 = new Employee("1001","tao1");
Employee e3 = new Employee("1002","tao2");
Employee e4 = new Employee("1003","tao3");
Employee e5 = new Employee("1004","tao4");
Employee e6 = new Employee("1005","tao5");
// System.out.println(e1.equals(e2));
// System.out.println(e2);
System.out.println(e1.hashCode());
System.out.println(e2.hashCode());
es.add(e1);
es.add(e2);
es.add(e3);
es.add(e4);
es.add(e5);
es.add(e6); System.out.println(es.size());
}
} class Employee{
String num;//员工编号
String name; Employee(String num,String name){
this.num = num;
this.name = name;
}
//重写equals方法,如果员工编号相同并且名字相同,则是同一个对象
public boolean equals(Object o){
if (this == o){
return true;
}
if (o instanceof Employee){
Employee e = (Employee) o;
if (e.num.equals(this.num) && e.name.equals(this.name))
{
return true;
}
}
return false;
}
//重写Hashcode方法
public int hashCode(){
//以员工编号分组,可散列均匀分布
return num.hashCode();
}
}
hashCode()的底层实现: public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
可以看到最终hash = s[0]31^(n-1) + s[1]31^(n-2) + ... + s[n-1];
涨知识:equals 和 == 你真的了解吗?的更多相关文章
- Java易混小知识——equals方法和==的区别
一.equals方法和==的区别 1.equals是String对象的方法,可以通过".“调用. 2.== 是一个运算符. 二.常用的比较用法 1.基本数据类型比较. equals和==都比 ...
- 涨知识Style
1.用Access作为后台数据库支撑,书写一个C#写入记录的案例 示例1: using System.Data.OleDb; string sql = "insert into 表 (列1, ...
- Camel——涨知识了,骆驼命名法
骆驼式命名法(Camel-Case)又称驼峰命名法,是电脑程式编写时的一套命名规则(惯例).正如它的名称CamelCase所表示的那样,是指混合使用大小写字母来构成变量和函数的名字.程序员们为了自己的 ...
- 涨知识,涨知识 :ThinkPHP框架下Where条件查询Mysql数据库某字段是否为空
代码虐我千百遍,我对代码如初恋~ 问题: 查询某字段app_date数据是否为NULL,正常我们实现的办法是: $map['app_data'] = array('eq','null'); $data ...
- main方法原来只要放在public static类中就能跑,涨知识了
接口中可以装在嵌套类对象. public interface ClassInterface { void howdy(); class Test implements ClassInterface { ...
- 你可能不知道的 10 条 SQL 技巧,涨知识了!
转自:http://mp.weixin.qq.com/s?__biz=MjM5NzM0MjcyMQ==&mid=2650076293&idx=1&sn=38f6acc759df ...
- 涨知识-VI 基于TCP/UDP的应用层协议
基于TCP/UDP的应用层协议: 基于TCP: Telnet(Teletype over the Network, 网络电传),通过一个终端(terminal)登陆到网络 FTP(File Trans ...
- 涨知识 --- VI
1.空类所占空间大小 空类所占空间为1,单一继承的空类空间也为1,多继承的空类空间还是1.但是虚继承涉及虚表(虚指针),所以sizeof(C)的大小为4. 2.内联函数与宏定义 Ans:内联函数和普通 ...
- 涨知识---V
1.内存对齐 在解释内存对齐的作用前,先来看下内存对齐的规则: 1). 对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数, ...
随机推荐
- Grafana + Prometheus 监控PostgreSQL
效果图 部署环境 服务器名称 IP地址 部署业务 备注 部署agent sht-sgmhadoopcm-01 172.16.101.54 PostgreSQL 监控服务器.被监控服务器 node_ex ...
- 【C/C++】小坑们
1.printf("%03d", a); // 输出 a,占 3 位,不够则左边用 0 填充 2.memcpy 所在头文件为 <string.h> 3.string s ...
- Eclipse错误集合
一.Could not write metadata for '/RemoteSystemsTempFiles'. 错误代码 Could not write metadata for '/Remote ...
- 路由器桥接尝试WDS
第一步:设置主路由器192.168.1.1. 第二步:设置副路由器. 进入副路由器的设置界面 点击「网络参数」->「LAN口设置」 把副路由器的LAN地址设置为192.168.1.2防止与主路由 ...
- freckles
题目描述: In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dad's back ...
- 1) 嵌套的 div ,或者 ul ol .li 阻止冒泡 ,特别是 对应onclick="test(event)" 通过传递event 阻止 冒泡. cancelBubble , stopPropagation
1 .html 结构: <ul class="ul_2 hide" data-first="5"> <li class="li_2& ...
- linux之安装软件,压缩解压文件
- 关于maven环境变量的配置问题
开始使用“MAVEN_HOME”配置完环境变量后,在cmd中输入mvn -v提示不是内部命令,后直接在PATH 路径里面添加maven所在的位置+\bin,比如,maven的路径为E:\maven\a ...
- Ubuntu Server 16.04设置WiFi
wifi :http://www.cnblogs.com/joeyupdo/p/3350463.html http://blog.csdn.net/meic51/article/details/173 ...
- 微信小程序传值以及获取值方法
http://www.51xuediannao.com/xiaochengxu/xiaochengxu-chuanzhi.html