list\set等容器(集合)那里重写equals为什么还要重写hashCode方法
来源:互联网 发布:python怎么输入 编辑:程序博客网 时间:2024/05/16 10:55
我们学些java j2se的时候为还说比较两个引用是否值(内容)相等的时候不去重写hashcode方法,只是重写equals方法呢:
一下是单纯重写equals方法的例子:
/**
* 测试重写equals方法
* @author Rick
*
*/
public class EqualsUsage {
String name;
public EqualsUsage(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean equals(Object obj) {
String name = ((EqualsUsage)obj).getName();
return this.name == name;
}
}
以下是测试类:
/**
* 验证重写equals的重写方法
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
EqualsUsage usage$1 = new EqualsUsage("Rick");
EqualsUsage usage$2 = new EqualsUsage("Rick");
EqualsUsage usage$3 = new EqualsUsage("Teddy");
System.out.println(usage$1.equals(usage$2));
System.out.println(usage$2.equals(usage$3));
}
}
输出结果:
true
false
由上面例子来讲,由于EqualsUsage的属性都是Rick,因此有两个引用的比较是true,因为我们重写了Object的equals方法,他们比较的是引用的属性值是否相等.
就好像两个筐装满水果的整体当作是硬盘,两个筐分别是不同的物理地址,第一个筐有苹果和菠萝,第二个筐有香蕉和菠萝
当我们没有重写equals方法的时候,我们默认调用Object类的equals方法,如果这样比较usage$1.equals(usage$2)
Object的equals方法如下:
/* @param obj the reference object with which to compare.
* @return {@code true} if this object is the same as the obj
* argument; {@code false} otherwise.
* @see #hashCode()
* @see java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);
}
就好像我们比较的是这两个筐的菠萝是不是在同一个筐(同一个物理地址)
如果现在我们的需求是,我们需要equals比较的是分别在这两个筐的菠萝到底是不是同一种水果(是不是同一对象),那我们就比较的就是它们的属性啦,是否名字相同,是否颜色,外形特征相同等等,重写的equals方法就是这么重写的.
但是他们的引用(地址)还是不会变的.
而在list和set等学习中,为什么不单只重写equals还要重写hashCode呢,原因如下
比如,一个"扒"字,如果在字典查找字典上对应的"扒",此时"pa"\"ba"这两个发音既是"扒"的属性,也是可以助你查找到"扒"字的索引。因此,当我们程序接收到"扒"字的时候,我们重写了equals获取到他的属性,知道操作的对象是什么,重写了hashcode,知道怎么去找到这个"字"的位置。
如下例子:
package com.j2se.hashCodeProblem;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
public class BasicContainer {
public static void main(String[] args) {
Collection c = new LinkedList();
c.add("hello");
c.add(new Name("f1","l1"));
c.add(new Integer(100));
c.add(new Name("f1","l1"));
System.out.println(c); //初始版本
/*c.remove("hello"); //不论一下有没有重写equals方法都会被删除,因为其本身已经重写equals方法,下同!!
c.remove(new Integer(100));
System.out.println(c.remove(new Name("f1","l1")));//没有重写hashcode是不能删除
System.out.println(c);*/
/*System.out.println(c);
System.out.println(new Integer(100));
System.out.println(new Integer(100) instanceof Integer);*/
//System.out.println(100 instanceof Integer); //编译有误
//System.out.println(true instanceof Boolean); //编译有误
/* System.out.println(new Boolean(true) instanceof Boolean);*/
System.out.println(c);
c.remove(new Name("f1","l1"));
System.out.println(c);
}
}
class Name implements Comparable<Name> {
private String firstName;
private String lastName;
public Name(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String toString() {
return firstName + " " + lastName;
}
/**
* 重写equals方法
*/
public boolean equals(Object obj) {
if (obj instanceof Name) {
Name name = (Name) obj;
return (firstName.equals(name.firstName))
&& (lastName.equals(name.lastName));
}
return super.equals(obj);
}
public int hashCode() {
return firstName.hashCode();
}
public int compareTo(Name name) {
Name n = (Name)o;
int lastCmp =
lastName.compareTo(n.lastName);
return
(lastCmp!=0 ? lastCmp :
firstName.compareTo(n.firstName));
}
}
可以再结合String源码对hashcode的具体实现进一步了解,
然而注意的是两个对象的hashcode相同,equals比较也返回true,他们的物理地址仍不一定相同.
总结:什么时候需要重写hashcode呢,就是当你的对象作为索引的时候!
- list\set等容器(集合)那里重写equals为什么还要重写hashCode方法
- 为什么重写了equals方法后,还要重写hashcode方法
- 为什么重写了equals(),还要重写hashCode()?
- 为什么重写了equals()之后还要重写hashCode()
- 为什么要在重写了equals方法时还要重写hashcode方法
- 为什么重写equals方法要重写hashCode
- IDEA get/set/重写equals()、hashcode()\toString()等 方法快捷键
- 为什么要重写hashcode和equals方法
- 为什么要重写equals和hashCode方法
- 为什么要重写equals和hashcode方法
- 为什么要重写hashcode和equals方法?
- 快速重写equals、hashcode等方法汇总
- 为什么重写equals方法要重写hashCode方法
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- 为什么重写equals方法,一定要重写HashCode方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- 为什么重写equals方法,一定要重写HashCode方法?
- TypeScript生成随机数
- html加载背景图片
- c++11右值引用
- BlueROV-15: Modify the Drive Modes in Mavlink
- 第一课:Python读取.csv文件
- list\set等容器(集合)那里重写equals为什么还要重写hashCode方法
- 23种设计模式4--行为型模式(策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式)
- java eclipse 环境配置
- Java中synchronized的实现原理
- 符号扩展和无符号扩展
- 邻接矩阵的创建
- spring事物管理
- JQuery 易混点
- 利用可变长参数实现,批量参数空校验