java基础解析系列(十一)---equals、==和hashcode方法

java基础解析系列(十一)---equals、==和hashcode方法

目录

==

  • 基本数据类型==比较的是值
类型 字节数
float 4
double 8
byte 1
short 2
int 4
long 8
char 2
boolean
  • 非基本数据类型,也就是引用型变量,==比较的是指向的内存地址

equals

  • Object类的的equals方法内部是用==比较,也就是比较地址
public boolean equals(Object obj) {
        return (this == obj);
    }
  • 而如果不同类会重写equals方法,比如String内部的equals比较的字符串的内容是否一样
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;
    }

hashcode方法

作用

  • 如果没有hashcode方法,在往一个set(不允许重复)添加的元素的时候,那么就得将全部的元素检查一遍equals,如果有hashcode方法,一个对象的hashcode会映射到一个位置,在这个位置检查是否存在即可,所以不需要全部检查。可以看看hashmap的put方法
public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }
  • 从源码可以看到,先通过hash值找到在table中的位置,然后再进行查找,这样就减少了执行equals的次数

equals方法和hashcode方法

  • equals方法返回true,hashcode一定相同
  • equals方法返回flase,hahscoe不一定不同

修改了equals方法

  • 前面已经了解过,Object的equals返回两个对象的内存地址是否相同,而Object类的子类经常会重写equals方法,比如两个People对象,比较的不是两个People对象的内存地址,而是比较name,age等属性,只要name和age相同就认为是同一个对象
  • 如果只重写了equals而不重写hashcode方法,下面进行测试
public static void main(String[] args) throws Exception {
        HashMap hashMap=new HashMap<Person,Integer>();
        Person p1=new Person("jiajun",18);
        Person p2=new Person("jiajun",18);
        System.out.println("这两个对象在设置的时候应该是相同的");
        hashMap.put(p1,666);
        System.out.println("那么按照我们的设计思路,我们通过p2应该可以得到666");
        System.out.println(hashMap.get(p2));
        System.out.println("可是这时候输出的却是null");
}
class Person
{
    String name;
    int age;
    public Person(String name,int age)
    {
        this.name=name;
        this.age=age;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if(this.getClass()!=obj.getClass())
        {
            return false;
        }
        People p = (People)obj;
        return this.name.equals(p.name)
                && this.age == p.age;
    }

}
  • 从实验结果可以看出,如果重写了equals方法而不重写hashcode方法容易出现问题

Effective java的建议

  • 在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法必须始终如一地返回同一个整数
  • 如果两个对象进行equals比较是相等的,那么这两个对象的hashcode方法必须返回相同的整数结果
  • 如果两个对象进行equals比较是不同的,那么这个两个对象hahscode方法不一定返回不同的整数

我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)

作者:jiajun 出处: http://www.cnblogs.com/-new/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。

时间: 2024-10-07 12:38:32

java基础解析系列(十一)---equals、==和hashcode方法的相关文章

Java提高篇——equals()与hashCode()方法详解

java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继承结构的基础,所以是每一个类的父类.所有的对象,包括数组,都实现了在Object类中定义的方法. equals()方法详解 equals()方法是用来判断其他的对象是否和该对象相等. equals()方法在object类中定义如下: public boolean equals(Object obj)

【转】Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例

原文地址:http://www.cnblogs.com/luankun0214/p/4421770.html 感谢网友的分享,记录下来只为学习. 1.重写equals方法实例   部分代码参考http://blog.csdn.net/wangloveall/article/details/7899948 重写equals方法的目的是判断两个对象的内容(内容可以有很多,比如同时比较姓名和年龄,同时相同的才是用一个对象)是否相同 如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址

Java中的equals和hashCode方法

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

Linux运维系统工程师与java基础学习系列-8

Java天生骄傲系列-8 函数的应用(重点掌握) 如何定义函数 例1: package test.myeclipse;                 publicclass test1 { publicstaticvoid main(String[]args) { int Sum = getSum(); System.out.println("Sum="+Sum); } publicstaticint getSum() { return 3+4; } } 运行结果:Sum=7 例2:

Linux运维系统工程师与java基础学习系列-4

Java天生骄傲系列-4 程序流程控制 判断 选择 循环 判断结构: If语句三种格式: 1.  if(条件表达式) { 执行语句: } 2.  if(条件表达式) { 执行语句: } else { 执行语句: } 3.  if(条件表达式) { 执行语句: } else if (条件表达式) { 执行语句: } --. else { 执行语句: } if(条件表达式) { 执行语句: } 牛刀小试: package test.myeclipse; publicclass test1 { pub

java基础巩固系列(二):Integer与int之间的区别

在JDK1.5之后引入了自动装箱(autoboxing)与自动拆箱(unboxing),这让很多对java的初学者感到很疑惑,我刚才也是其中一员. 首先,有一些基本的概念需要了解: 1.Ingeter是int的包装类,int的初值为0,Ingeter的初值为null. 2.Integer是一个类,用Integer声明一个变量是一个对象类型(或者说引用类型):int是基本类型,用int声明的变量是非对象类型,即不能在其上调用方法. 3."=="作用于对象上的时候,其比较的是对象的引用本身

Linux运维系统工程师与java基础学习系列-2

Java天生骄傲系列-2 运算符 1.   算术运算符 注: 1)"+"号除了用于加法运算以外,还用作字符串连接符: 2)字符串数据和任何数据使用+都是相连接,最终都会变成字符串. package day4javatest.myeclipse;         publicclass day4test1 { /** * @param args */ publicstaticvoid main(String[]args) { // TODO Auto-generated method s

Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例

1.重写equals方法实例   部分代码参考http://blog.csdn.net/wangloveall/article/details/7899948 重写equals方法的目的是判断两个对象的内容(内容可以有很多,比如同时比较姓名和年龄,同时相同的才是用一个对象)是否相同 如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等.特别指出利用equals比较八大包装对象(如int,float等)和String类(因为该

Linux运维系统工程师与java基础学习系列-1

Java天生骄傲系列-1 1     Eclipse的使用(略): 2 在eclipse下Java程序的编写和运行,及Java运行环境的配置略: 3 快捷键的配置,常用快捷键(略): 注:当程序有错误的时候,我们才会采取debug的方式去运行程序! 4 程序的调试和运行:以断点的方式去查看程序出现的问题. 断点调试常用功能(快捷键): F5(跳入)      F6(跳过)      F7(跳出) drop to frame:跳到当前方法的第一行: resume:跳到下一个断点(如果没有下一个,则