zoukankan      html  css  js  c++  java
  • Object类----toString,equals,hashcode

    一。toString 的应用方法与覆写

    public class testoveridetoString {

    public static void main(String[] args) {

    /*objectmode1 a = new objectmode1();
    System.out.println(a); //直接打印a,相当于a.toString()
    //project1.objectmode@15db9742 输出的是一行不能理解的结果*/
    objectmode2 b = new objectmode2();
    System.out.println(b); //输出正确结果 "i am "+name+",i am "+age+" years old!“
    }
    }

    class objectmode1 //没有覆写toString方法的类
    {
    final int age = 9;
    String name = "alice";
    }
    class objectmode2 //覆写toString方法的类
    {
    final int age = 10;
    String name = "tom";
    public String toString() //覆写,注意返回值类型要与Object类中相同
    {
    return "i am "+name+",i am "+age+" years old!";
    }
    }

    二。equals方法的应用与覆写

    因为equals比较的是地址,所以即使实例对象的内容相同,返回值也为假,这里直接提供equals的覆写方法

    public boolean equals(Object o)

    {

    boolean temp = true;

    Object p1 = this;   //Object 指一个特定的类,根据情况修改 ,this 指的是调用equals的对象

    if(o instanceof Object)//判断o是不是该类的一个实例

    {

    Object p2 = (Object)o; //如果是,向下转型

    if(!p1. **.equals(p2. **)&&**)//  **表示类的属性

    {

    temp = flase;

    }

    }

    else

    {

    temp = flase;

    }

    return temp;

    }

    三。hashCode方法的使用与覆写

    public int hashCode()   //覆写

    {

    return id*(name.hashCode());

    }

    在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。 
    如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。 

    总结:等价的(调用equals返回true)对象必须产生相同的散列码。不等价的对象,不要求产生的散列码不相同

    两个对象值相同(x.equals(y) == true),则一定有相同的hash code。

    这是Java语言的定义: 

    因为:Hash,一般翻译做“散列”,也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。
    1) 对象相等则hashCode一定相等;
    2) hashCode相等对象未必相等。

    == 是比较地址是否相等,JAVA中声明变量都是引用嘛,不同的引用,可能指向同一个地址

    equals 是比较值是否相等。

    这种题很容易在面试中被问到。。。

    hash code、equals和“==”三者的关系

    1.如果是基本变量,没有hashcode和equals方法,基本变量的比较方式就只有==,;

    2.如果是变量,由于在java中所有变量定义都是一个指向实际存储的一个句柄(你可以理解为c++中的指针),在这里==是比较句柄的地址(你可以理解为指针的存储地址),而不是句柄指向的实际内存中的内容,如果要比较实际内存中的内容,那就要用equals方法,但是!!!

    如果是你自己定义的一个类,比较自定义类用equals和==是一样的,都是比较句柄地址,因为自定义的类是继承于object,而object中的equals就是用==来实现的,你可以看源码。

    那为什么我们用的String等等类型equals是比较实际内容呢,是因为String等常用类已经重写了object中的equals方法,让equals来比较实际内容,你也可以看源码。

    3. hashcode
    在一般的应用中你不需要了解hashcode的用法,但当你用到hashmap,hashset等集合类时要注意下hashcode。

    你想通过一个object的key来拿hashmap的value,hashmap的工作方法是,通过你传入的object的hashcode在内存中找地址,当找到这个地址后再通过equals方法来比较这个地址中的内容是否和你原来放进去的一样,一样就取出value。

    所以这里要匹配2部分,hashcode和equals
    但假如说你new一个object作为key去拿value是永远得不到结果的,因为每次new一个object,这个object的hashcode是永远不同的,所以我们要重写hashcode,你可以令你的hashcode是object中的一个恒量,这样永远可以通过你的object的hashcode来找到key的地址,然后你要重写你的equals方法,使内存中的内容也相等。。。

    首先,从语法角度,也就是从强制性的角度来说,hashCode和equals是两个独立的,互不隶属,互不依赖的方法,equals成立与hashCode相等这两个命题之间,谁也不是谁的充分条件或者必要条件。  
       
      但是,从为了让我们的程序正常运行的角度,我们应当向Effective   Java中所言  
       
      重载equals的时候,一定要(正确)重载hashCode  
       
      使得equals成立的时候,hashCode相等,也就是a.equals(b)->a.hashCode()   ==   b.hashCode(),或者说此时,equals是hashCode相等的充分条件,hashCode相等是equals的必要条件(从数学课上我们知道它的逆否命题:hashCode不相等也不会equals),但是它的逆命题,hashCode相等一定equals以及否命题不equals时hashCode不等都不成立。  
       
      所以,如果面试的时候,最好把hashCode与equals之间没有强制关系,以及根据(没有语法约束力的)规范的角度,应当做到...这两层意思都说出来:P  

      总结一下,equals()是对象相等性比较,hashCode()是计算对象的散列值,当然他们的依据是对象的属性。

     对于equals,一般我们认为两个对象同类型并且所有属性相等的时候才是相等的,在类中必须改写equals,因为Object类中的equals只是判断两个引用变量是否引用同一对象,如果不是引用同一对象,即使两个对象的内容完全相同,也会返回false。当然,在类中改写这个equals时,你也可以只对部分属性进行比较,只要这些属性相同就认为对象是相等的。  
       
      对于hashCode,只要是用在和哈希运算有关的地方,前面很多兄弟都提到了,和equals一样,在你的类中也应该改写。当然如果两个对象是完全相同的,那么他们的hashCode当然也是一样的,但是象前面所述,规则可以由你自己来定义,因此两者之间并没有什么必然的联系。  
       
      当然,大多数情况下我们还是根据所有的属性来计算hashCode和进行相等性比较

  • 相关阅读:
    bzoj4195 [Noi2015]程序自动分析
    bzoj4236 JOIOJI hash 模拟
    bzoj1012 [JSOI2008]最大数maxnumber
    day 4 名片管理系统 -函数版
    day 3 局部变量 全局变量
    day 2 函数的嵌套
    day1 函数 (独立功能代码块)
    day 14 元组
    day 13 字典dict 操作
    day 12 列表字典 补充
  • 原文地址:https://www.cnblogs.com/2206411193qzb/p/7371428.html
Copyright © 2011-2022 走看看