基本概念

  • ==是运算符,比较的是两个变量是否相等;
  • 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 和 == 你真的了解吗?的更多相关文章

  1. Java易混小知识——equals方法和==的区别

    一.equals方法和==的区别 1.equals是String对象的方法,可以通过".“调用. 2.== 是一个运算符. 二.常用的比较用法 1.基本数据类型比较. equals和==都比 ...

  2. 涨知识Style

    1.用Access作为后台数据库支撑,书写一个C#写入记录的案例 示例1: using System.Data.OleDb; string sql = "insert into 表 (列1, ...

  3. Camel——涨知识了,骆驼命名法

    骆驼式命名法(Camel-Case)又称驼峰命名法,是电脑程式编写时的一套命名规则(惯例).正如它的名称CamelCase所表示的那样,是指混合使用大小写字母来构成变量和函数的名字.程序员们为了自己的 ...

  4. 涨知识,涨知识 :ThinkPHP框架下Where条件查询Mysql数据库某字段是否为空

    代码虐我千百遍,我对代码如初恋~ 问题: 查询某字段app_date数据是否为NULL,正常我们实现的办法是: $map['app_data'] = array('eq','null'); $data ...

  5. main方法原来只要放在public static类中就能跑,涨知识了

    接口中可以装在嵌套类对象. public interface ClassInterface { void howdy(); class Test implements ClassInterface { ...

  6. 你可能不知道的 10 条 SQL 技巧,涨知识了!

    转自:http://mp.weixin.qq.com/s?__biz=MjM5NzM0MjcyMQ==&mid=2650076293&idx=1&sn=38f6acc759df ...

  7. 涨知识-VI 基于TCP/UDP的应用层协议

    基于TCP/UDP的应用层协议: 基于TCP: Telnet(Teletype over the Network, 网络电传),通过一个终端(terminal)登陆到网络 FTP(File Trans ...

  8. 涨知识 --- VI

    1.空类所占空间大小 空类所占空间为1,单一继承的空类空间也为1,多继承的空类空间还是1.但是虚继承涉及虚表(虚指针),所以sizeof(C)的大小为4. 2.内联函数与宏定义 Ans:内联函数和普通 ...

  9. 涨知识---V

    1.内存对齐 在解释内存对齐的作用前,先来看下内存对齐的规则: 1).  对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数, ...

随机推荐

  1. vscode settings.json

    // 快捷键设置 keyiing.json // 将键绑定放入此文件中以覆盖默认值 [ /* // 转换大写 { "key" : "ctrl+shift+u", ...

  2. 网络编程—网络基础概览、socket,TCP/UDP协议

    网络基础概览 socket概览 socket模块—TCP/UDP的实现 TCP/UDP总结 网络基础概览 osi七层协议各层主要的协议 # 物理层传输电信号1010101010 # 数据链路层,以太网 ...

  3. 超恶心的TP模版取值

    一.JS事件中 在使用H-uiAdmin做后台开发的时候,碰到了使用元素点击触发js函数展示弹窗的写法 但是在js函数中还需要使用U函数生成url以及使用$vo.id来传值 反复试了一下模版标签的写法 ...

  4. RAID的基本介绍

    一.传统磁盘的劣势 影响计算机性能的组件一般包括:CPU.主板总线IO.内存IO.硬盘IO.网卡IO.现代处理器性能已经很高了,但是计算机整体IO性能较弱,严重影响了计算机性能 现代的计算机总线.内存 ...

  5. vscode 创建.net core mvc

    cd 进一个文件夹 1,创建一个sln 工程文件  [ dotnet new sln -n Demo1 ] 2,创建一个mvc项目 [ dotnet new mvc -n Demo1.Web ] 3, ...

  6. 浮动滚动条 slimScroll

    1.引入jquery 2.映入slimScrolljs :<script src="https://cdn.bootcss.com/jQuery-slimScroll/1.3.8/jq ...

  7. Android开发 ---xml构建选项菜单、上下文菜单(长按显示菜单)、发通知、发送下载通知

    1.activity_main.xml 描述: 定义了一个TextView和三个按钮 <?xml version="1.0" encoding="utf-8&quo ...

  8. Windows 应用商店无法下载---启动更新

    今天想在应用商店下载东西,但是以直没成功,查看原因结果是因为我的Windows自动更新关了. 百度,如何打开自动更新,要打开本地组策略编辑器,但是我是Windows家庭版,,,没有这个东西,, 最后, ...

  9. 05_解决mac百度网盘下载速度慢问题

    第一步:下载软件 下载工具包:aria2GUI和chrom插件 链接:https://pan.baidu.com/s/104t6aZXx9zfxBV9rS_eLfg  密码:yg96 ①下载Aria2 ...

  10. Python学习笔记第二十六周(Django补充)

    一.基于jQuery的ajax实现(最底层方法:$.jax()) $.ajax( url: type:''POST“ ) $.get(url,[data],[callback],[type])  #c ...