Java中的Object类 (上篇)

版权声明:知识本无差别,何必在意你我? https://blog.csdn.net/qq_33774822/article/details/82757065

 

 要么读书,要么旅行,身体和心灵总有一个要在路上。——罗马假日

咱今天学习的是Java的Object类,首先先看代码,类里面有哪些方法。

咱今天学习两个方法,分别是hashCode,equals。

 Object中的hashCode方法就是根据一定的规则与对象相关的信息映射成一个数值,这个数值称为散列值。

  public native int hashCode();

这时有个关键字native,Java平台有个用户和本地C代码进行交互操作的API,称为Java Native Interface(简称为JNI)。

 Object中的equals方法是用来比较两个对象是否相等的,即object1.equals(object2)为true,则表示object1和object2实际上是引用的同一个对象,但是我们大部分时候进行的是两个对象值的比较,而非地址的比较,所以这个时候,Object的equals方法就不行了。

这时候有的小哥哥要说不对啊,我们平常也使用了String,Integer,Long类型也进行了equals比较啊,他是比较的值,而非地址,你这不会瞎扯淡吧。

不慌不慌,咱慢慢看,先上代码看一下,如果是String类型,使用equals是不是比较的值。

public class Test {
  public static void main(String[] args){
     String str1="abc";
     String str2="abc";
     System.out.println(str1.equals(str2));
  }
}

 咱运行下代码,会发现的确打印的true,说明是比较了str1和str2的值。因为在上篇我们说过了str是一个常量,每次的string类型的数据的地址都是不一样的,不明白的可以移步上篇,https://blog.csdn.net/qq_33774822/article/details/82757055,那不打脸了吗。

开玩笑,怎么可能打脸呢,那咱来看一下这个为什么呢

原来啊,是String类里面重写了equals方法,980行到994行之间就是对两个string类型数据的比较。感谢Java粑粑,这时候是不是应该响起一首歌,你还要我怎样,要怎样。


 但是这是常见的类型,那比如我们自定义了一个对象类型,要比较两个对象是否相等,那该怎么做呢,应该是重写equals方法,这里说明一下,如果两个对象通过equals来比较返回的是true,就说明这两个值相等,那么这两个对象的hashCode也应该返回相同的值。这是hashCode的常规规定,咱必须得遵守呢。

hashCode还有一个规定就是在程序运行时,同一对象多次调用hashCode方法应该返回相同的值。

基于以上的两个规定,我们自定义了一个Person类,里面有id,name,还重写了equals和hashCode方法。

上代码咯:

public class Person {

  private String id;
  private String name;

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  @Override
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    }
    if (!(o instanceof Person)) {
      return false;
    }
    Person person = (Person) o;
    return person.getId().equals(id) && person.getName().equals(name);
  }

  @Override
  public int hashCode() {
    int result = 17;
    result = result * 31 + name.hashCode() + id.hashCode();
    return result;
  }
}

这里要重点说明一下重写hashCode的时候,用的是31来乘以result,这是为了让产生的hashCode唯一。

主要的原因有两个:

1.更少的乘积结果冲突。31是质数中不大不小的存在,如果使用如3这样比较小的质数,那么得出的乘积会在一个很小的范围内,很容易造成哈希值冲突。如果选择100以上的质数,得到的哈希值会超过int的最大范围。所以这两种都不适合。

2.31可以被JVM优化,31=2<<5-1,JVM可以自动识别为位运算。

猜你喜欢

转载自blog.csdn.net/qq_33774822/article/details/82757065
今日推荐