关于equals、hashcode和集合类的小结

一.首先明确一点:equals()方法和hashcode()方法是Object类里的方法

  查看源码可以知道,在Object类中equals(obj)方法直接返回的是  this ==
obj
 的值。对于引用变量来说,这个式子判断的是变量中存储的内存地址是否一致。而hashcode()方法的出现,目的是为了提高哈希表的性能,也就是说,提供这样一个方法是为了提高依据hashcode进行存取的数据结构的性能的。

 两者的关系:

 在Object类的注释中可以看到两个原则:

 两个类如果通过equals()方法比较返回的值为true,则这两个类调用hashcode()方法返回的整数值必须相等。

 两个类如果通过equals()方法比较返回的值为false,则这两个类调用hashcode()方法返回的整数值建议不同(hashcode的初衷),可以相等。

 故在Object类中:

 equals()方法比较的方式是比较两个引用的内存地址,对于任何新 new 出来的对象来说,他们的内存地址都是不一样的。而Object类默认的hashcode计算方式和类的内存地址相关,所以他们的hashcode是不同的。


package com.njsteel.test;

public class Test {
public static void main(String[] args){

Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = obj1;

obj1.hashCode();//14576877
obj2.hashCode();//12677476
obj3.hashCode();//14576877

obj1.equals(obj2);//false
obj1.equals(obj3);//true
}
}

  故,我们自定义的所有类,如果没有重写equals()方法和hashcode()方法,则都是满足上述的情况的。因为自定义的类都是Object类的子类。

二. 其次,Java提供的很多便捷类都会重写equals()和hashcode()方法。

   这里只说明一下String类的情况。

为什么String类要重写equals()和hashcode()方法?

一般来说,当我们想判断两个String类对象的内容是否相同时,我们就会调用equals()方法,这是API文档告诉我们的。我们比较时,一般是两个不同对象的引用。这时候,即使String对象的内容相同,如果按照Object类里equals()的判断方法判断,返回的值始终都是false。

所以为了满足这样的需要,String类equals()方法重写添加了根据内容判断两个String对象内容是否相同的逻辑代码。

equals()被重写后,hashcode()自然也要被重写,因为重写的equals()方法破坏了Object类中规定的两者的关系。于是String类里的hashcode()方法也重写成了和String内容相关的样子。以满足原来的关系。

其他的类就可以按照这样的情况以此类推。。

三. 和某些集合类的关系

先说Set:

在看书的时候,对于Set的描述有:Set集合不允许包含相同的元素

在Set里,相同的元素是指通过equals()方法返回值为true的两个对象。在调用Set的add()方法时,就会进行这个判断(add进来的元素会与Set集合里已经有的所有元素进行equals判断,如果有相同,则add()方法返回false,添加失败)。

对于HashSet类:

HashSet是Set接口的一个实现,自然也是不允许包含相同的元素。不过判断的方法和原始的Set有点不同。

往HashSet集合里添加元素时,它不仅会通过equals()方法判断,还要调用hashcode()方法判断。只有当两个元素equals相等,并且hashcode也相等时,两个元素才是相同的元素。当其中有一个方法比较显示两个元素不一样时,HashSet会将其添加。

对于HashMap类:

我们知道HashMap的Key值是不能重复的。其实HashMap的Key值是保存在一个Set()集合里的。所以,作为Key,至少他们的hashcode是不相同的。如果两个对象是相同的Key(equals相等,hashcode也相同),值会覆盖。

验证代码:


package com.njsteel.test;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class HashSetTest {
public static void main(String[] args){
Set<MyString> set_1 = new HashSet<MyString>();
MyString myString1 = new MyString();
MyString myString2 = new MyString();
//添加一个元素
set_1.add(myString1);
//添加一个equals返回true,但是hashcode不同的元素
System.out.println(myString1.equals(myString2)+"!!!"+myString1.hashCode()+"/"+myString2.hashCode());
System.out.println(set_1.add(myString2));//true,添加成功。

//添加一个元素
Set<MyTestObject> set_2 = new HashSet<MyTestObject>();
set_2.add(new MyTestObject());
//添加一个equals返回false,但是hashcode相同的元素。
System.out.println(set_2.add(new MyTestObject())+""+set_2.size());

Map<MyString,String> map = new HashMap<MyString,String>();

map.put(myString1, "1");
map.put(myString2, "2");
for(Object key : map.keySet()){
System.out.println(map.get(key));
}

}
}

class MyString{

@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return true;
}

@Override
public int hashCode() {
// TODO Auto-generated method stub
return super.hashCode();
}

}

class MyTestObject{

@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return false;
}

@Override
public int hashCode() {
// TODO Auto-generated method stub
return 1;
}

}
 

 欢迎讨论指正。。

关于equals、hashcode和集合类的小结,布布扣,bubuko.com

时间: 2024-11-01 23:39:12

关于equals、hashcode和集合类的小结的相关文章

讲的很详细的一篇关于object equals() &amp; hashCode() 的文章

转: 讲的很详细的一篇关于object equals() & hashCode() 的文章 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现. 为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方

java 笔记 == , equals , hashcode()的区别

== , equals , hashcode()的区别: 基本数据类型:比较用==, 比较他们的值 复合数据类型:用==比较时,比较的是它们在内存中存放的地址,除非是同一个new出来的对象,他们的比较后果为true,否则为false. object基类中定义了equals()方法,它的初始行为是比较它们的内存地址(就是和==功能一样),但在有些类库中覆盖了,比如String类的equals()方法是比较它们的内容.equals()方法在object类中定义如下:   public boolean

equals(),hashcode(),克隆学习心得

equals(),hashcode(),克隆学习心得 其实在开发时候,很少去重写equals(),hashCode()方法,但是有些时候业务需要还是要重写. 注意: 重写equals()方法一定要重写hashCode()方法. notes: java中两个对象的比较,首先查看的就是一个对象的hashCode,可以把hashCode理解为索引,通过索引可以找到其对应下的内容,可能会有多个. 如果说两个对象的hashCode都不相等,那可以肯定这个对象不同. equals() 相等的两个对象,其ha

== equals hashCode 总结比较

在Java中: ==是运算符,用于比较两个变量是否相等. equals,是Objec类的方法,用于比较两个对象是否相等,默认Object类的equals方法是比较两个对象的地址,跟==的结果一样.Object的equals方法如下: [java] view plain copy public boolean equals(Object obj) { return (this == obj); } hashCode也是Object类的一个方法.返回一个离散的int型整数.在集合类操作中使用,为了提

equals,hashCode,牢记

1.equals 2.hashCode 3.  4. 5. 6

equals(),hashcode()方法详解

Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用. equals()和hashCode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类对象时用来判断放入的对象是否重复. 这里我们首先要明白一个问题: equals()相等的两个对象,hashcode()一定相等,equals()不相等的两个对象,却并不能证明他们的hashcode()不相等.换

学习笔记------- == &#160; equals &#160; hashcode

先来回顾一下 == 与equals 的区别 ==是运算符 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean ,他们之间的比较,应该用双等号(==),比较的是他们的值. 2.引用数据类型,比如字符串,或者一个类的对象   当他们用(==)进行比较的时候,实际上比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false.

Java ==,equals,hashCode,解析(适合初学者阅读)

1.对于equals()和hashCade()方法他们都是位于Java.lang.object类下的方法,又因为所有的类都继承于objct类,所以所有的类都可以使用这两个方法. 2.对于equals()方法,首先知道他是用于比较的,这里我吧源码打出来(注意:我这打出的源码是Object类中的equals()方法的源码) public boolean equals(Object obj){ return (this==obj); } 附录:this关键字我在这里进行简单的说明一下吧,对于初学者对t

equals hashcode toString 方法的使用

package com.wu.toString; import java.util.Date; import java.util.GregorianCalendar; /** * * @author wuyong * @email [email protected] * @date2016年9月1日下午4:39:09 * 雇员类 */ class Employee { private String name; private double salary;//薪水 private Date hir