涨知识: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()指定的数, ...
随机推荐
- jquery 获取表单的内容以JSON对象形式返回
添加一个serializeJson方法 <!DOCTYPE html> <html> <head> <meta charset="UTF-8&quo ...
- Android 音视频深入 十二 FFmpeg视频替换声音(附源码下载)
项目地址,求starhttps://github.com/979451341/AudioVideoStudyCodeTwo/tree/master/FFmpeg%E7%BB%99%E8%A7%86%E ...
- 入坑deep learning 1
想体验一下跑keras的感觉,按照这个小妹妹的教程:https://zhuanlan.zhihu.com/p/28333410 0. 大概花了十来个小时才搞定初步的小环境 1. 在linux 16.0 ...
- SQL配置的坑
我要被自己蠢哭了,新做了一台电脑装SQL sever为了存数据,配置完,突然间发现MSSQLSEVER 不能重新启动,相当于之前的配置,还IP都白弄了.我找原因找了3个小时,后来发现是手欠启动的不该启 ...
- 2019-04-11-day030-网络编程并发
内容回顾 黏包 tcp协议为了保证数据的可靠传输和传输效率 合包机制 : 连续多条短数据会合并成一条 拆包机制 : 一个过大的数据会在发出之前被拆成几个小包 tcp的黏包发生在两端: 发送端 : 合包 ...
- 网站文档模式总是以Quirks文档模式解析网站
<meta name="renderer" content="webkit"/> <meta http-equiv="X-UA-Co ...
- TCP/IP笔记(1)
TCP/IP 背景和介绍 上世纪 70 年代,随着计算机技术的发展,计算机使用者意识到:要想发挥计算机更大的作用,就要将世界各地的计算机连接起来.但是简单的连接是远远不够的,因为计算机之间无法沟通.因 ...
- switch和数组两种方法对不同输入做不同响应
#include<stdio.h> int main(void) { int i; scanf("%d",&i); switch(i) { : printf(& ...
- javax/servlet/jsp/jstl/core/Config
javax/servlet/jsp/jstl/core/Config springmvc出现的问题. 尝试了各种jar,问题依旧. DispatcherServlet配置如下. <bean id ...
- $inject
function breadcrumb($parse, store) { } // 为了压缩 breadcrumb.$inject = ['$parse', 'breadcrumbStore']