我想写的问题有三个:

1、首先我们为什么需要重写hashCode()方法和equals()方法

2、在什么情况下需要重写hashCode()方法和equals()方法

3、如何重写这两个方法

*********************************************************************

第一个问题:为什么需要重写hashCode()方法和equals()方法

Java中的超类Object类中定义的equals()方法是用来比较两个引用所指向的对象的内存地址是否一致

Object类中equals()方法的源码

public boolean equals(Object obj) {
return (this == obj);
}

Object类中的hashCode()方法,用native关键字修饰,说明这个方法是个原生函数,也就说这个方法的实现不是用java语言实现的,是使用c/c++实现的,并且被编译成了DLL,由java去调用,jdk源码中不包含。对于不同的平台它们是不同的,java在不同的操作系统中调用不同的native方法实现对操作系统的访问,因为java语言不能直接访问操作系统底层,因为它没有指针。

这种方法调用的过程:

1、在java中申明native方法,然后编译

2、用javah产生一个  .h  文件

3、写一个 .cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(其中又包含了jdk带的jni.h文件);

4、将.cpp文件编译成动态链接库文件

5、在java中用System.loadLibrary()文件加载第四步产生的动态链接库文件,然后这个navite方法就可被访问了

Java的API文档对hashCode()方法做了详细的说明,这也是我们重写hashCode()方法时的原则【Object类】

重点要注意的是:

a.  在java应用程序运行时,无论何时多次调用同一个对象时的hsahCode()方法,这个对象的hashCode()方法的返回值必须是相同的一个int值

b.  如果两个对象equals()返回值为true,则他们的hashCode()也必须返回相同的int值

c.  如果两个对象equals()返回值为false,则他们的hashCode()返回值也必须不同

public native int hashCode();

现在到了说正题了,为什么要重写

我们在定义类时,我们经常会希望两个不同对象的某些属性值相同时就认为他们相同,所以我们要重写equals()方法,按照原则,我们重写了equals()方法,也要重写hashCode()方法,要保证上面所述的b,c原则;所以java中的很多类都重写了这两个方法,例如String类,包装类

4、第二个问题:在什么情况下需要重写hashCode()方法和equals()方法

当我们自定义的一个类,想要把它的实例保存在集合中时,我们就需要重写这两个方法;集合(Collection)有两个类,一个是List,一个是Set

List:集合中的元素是有序的,可以重复的

Set:无序,不可重复的

以HashSet来说明:

HashSet存放元素时,根据元素的hashCode值快速找到要存储的位置,如果这个位置有元素,两个对象通过equals()比较,如果返回值为true,则不放入;如果返回值为false,则这个时候会以链表的形式在同一个位置上存放两个元素,这会使得HashSet的性能降低,因为不能快速定位了。还有一种情况就是两个对象的hashCode()返回值不同,但是equals()返回true,这个时候HashSet会把这两个对象都存进去,这就和Set集合不重复的规则相悖了;所以,我们重写了equals()方法时,要按照b,c规则重写hashCode()方法!

5、第三个问题:如何重写这两个方法

我写了一个例子,大家可以看一下

*******************************************************************************

package cn.hashCode.jing;

/**

*定义一个Ponint测试类,用来测试Set集合保存元素的方式中

*hashCode()方法和equals()方法对Set集合保存元素影响

*

*/

public final class Point {

private int x;

private int y;

public Point(){

super();

}

public Point(int x,int y){

this.x=x;

this.y=y;

}

public int getX() {

return x;

}

public void setX(int x) {

this.x = x;

}

public int getY() {

return y;

}

public void setY(int y) {

this.y = y;

}

@Override

public boolean equals(Object obj){

if(this==obj){

return true;

}

if(obj!=null && obj.getClass()==Point.class){

Pointpo=(Point)obj;

if(this.x==po.x && this.y==po.y){

return true;

}

}

return false;

}

@Override

public int hashCode(){

return 7*x+31*y;

}

/*以下是自动生成的

@Override

publicboolean equals(Object obj) {

if(this == obj)

returntrue;

if(obj == null)

returnfalse;

if(getClass() != obj.getClass())

returnfalse;

Pointother = (Point) obj;

if(x != other.x)

returnfalse;

if(y != other.y)

returnfalse;

returntrue;

}

@Override

publicint hashCode() {

finalint prime = 31;

intresult = 1;

result= prime * result + x;

result= prime * result + y;

returnresult;

}*/

public String toString(){

return x+","+y+" ";

}

}

package cn.hashCode.jing;

import java.util.HashSet;

public class TestHashSet {

public static void main(String[] args) {

HashSet<Point>hs=new HashSet<Point>();

Pointp1=new Point(3,4);

Pointp2=new Point(6,4);

Pointp3=new Point(10,7);

Pointp4=new Point(8,9);

Pointp5=new Point(3,4);

hs.add(p1);

hs.add(p2);

hs.add(p3);

hs.add(p4);

hs.add(p5);

System.out.println(p1.equals(p5));

System.out.println(p1.hashCode());

System.out.println(p5.hashCode());

System.out.println(hs);

}

}

结果:true

145

145

[3,4 , 6,4 , 10,7 ,8,9 ]

可以自己试一下,hashCode()返回值相等,equals()返回false;和hashCode()返回值不相等,equals()返回值为true;都会出现什么情况

为什么要重写hashCode()方法和equals()方法及如何重写的更多相关文章

  1. 为什么要重写hashcode方法和equals方法

    我们可能经常听到说重写equals方法必须重写hashcode方法,这是为什么呢?java中所有的类都是Object的子类,直接上object源码 /* * Copyright (c) 1994, 2 ...

  2. Java 重写hashCode 方法和equals方法

    package Container; import java.util.HashSet; import java.util.Iterator; /* Set 元素是无序的(存入和取出的顺序不一定一致) ...

  3. hashCode()方法和equals方法的重要性。

    在Object中有两个重要的方法:hashCode()和equals(Object obj)方法,并且当你按ctrl+alt+s时会有Generator hashCode()和equals().我们不 ...

  4. java 集合 HashSet 实现随机双色球 HashSet addAll() 实现去重后合并 HashSet对象去重 复写 HashCode()方法和equals方法 ArrayList去重

    package com.swift.lianxi; import java.util.HashSet; import java.util.Random; /*训练知识点:HashSet 训练描述 双色 ...

  5. hashCode方法和equals方法比较

    为什么用HashCode比较比用equals方法比较要快呢?我们要想比较hashCode与equals的性能,得先了解HashCode是什么. HashCode HashCode是jdk根据对象的地址 ...

  6. 【转】为什么要重写hashcode()方法和toString()方法

    Object 类 包含toString()和hashCode()方法. 一.toString(): 在Object类里面定义toString()方法的时候返回的对象的哈希code码,这个hashcod ...

  7. 集合hashCode()方法和equals()办法

    1.哈希码:         Object中的HashCode方法会返回该对象的的内存真实地址的整数化表示,这个形象的不是真正抵制的整数值就是哈希码. 2.利用哈希码向集合中插入数据的顺序?     ...

  8. java数组、java.lang.String、java.util.Arrays、java.lang.Object的toString()方法和equals()方法详解

    public class Test { public static void main(String[] args) { int[] a = {1, 2, 4, 6}; int[] b = a; in ...

  9. Object、String、数组的 toString() 方法和 equals() 方法及java.util.Arrays

    public class Test { public static void main(String[] args) { int[] a = {1, 2, 4, 6}; int[] b = a; in ...

随机推荐

  1. 有关Oracle统计信息的知识点[z]

    https://www.cnblogs.com/sunmengbbm/p/5775211.html 一.什么是统计信息 统计信息主要是描述数据库中表,索引的大小,规模,数据分布状况等的一类信息.例如, ...

  2. selenium无界面chromedriver

    chromeDriver下载地址:http://chromedriver.storage.googleapis.com/index.html 谷歌浏览器Chrome和驱动程序的对照表https://b ...

  3. c# 多个事件公用一个相应方法判断事件来源

    假设下边的相应方法有多个事件共同使用.根据事件的sender 判断来源,做相应的处理 假设事件来源DataManSystem;private void OnSystemConnected(object ...

  4. EmguCV Image类中的函数(二)使用MorphologyEx进行更多的变换

    MorphologyEx中所有的变换如下图所示 调用方法: Mat aaa = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.R ...

  5. 继承 (js原型链)

    原型链是实现继承的主要方法.基本思想:利用原型让一个引用类型继承另一个引用类型的属性和方法. 1.构造函数.原型.实例的关系: 每个构造函数都有原型属性(Prototype),指向一个原型对象(函数创 ...

  6. 前端面试问题css汇总

    1,行内元素有哪些?块级元素有哪些?空元素有哪些?CSS的盒模型? 块级元素:div p h1 h2 h3 h4 form ul li 行内元素: a b br i span input select ...

  7. Android.InstallAntOnMacOSX

    在Mac OS X上安装ant http://blog.csdn.net/crazybigfish/article/details/18215439

  8. Expressions入门示例

    学习表达式的入门例子,前提是要对委托有一定的了解,泛型明白一些.using System; using System.Linq; using System.Linq.Expressions; usin ...

  9. Windows下的PHP 5.3.x安装 Zend Guard Loader

    PHP5.3之后不再使用Zend Optimizer而是由Zend Guard Loader替换,而Zend Guard Loader安装比前者方便了很多,只有一个dll: 址:http://down ...

  10. Java的反射技术

    什么是反射机制 Java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能调用它的任意属性和方法.这种动态获取信息以及动态调用对象属性和方法的即使称为J ...