看图说话

Object有以下几个方法

  • getClass()

    final类型,主要是用来获得运行时的类型

  • hashCode()

    返回该对象的哈希码值,方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。该方法常用于hash查找,重写equals方法一般都要重写hashCode方法

  • equals()

    equals方法一般和==是不一样的,但是在Object中,两者一样。子类一般都要重写这个方法

  • clone()

    创建并返回对象的副本,它实现对象的浅复制

  • toString()

    返回对象的字符串表示

  • notify()

    唤醒在该对象上等待的某个线程

  • notifyAll()

    唤醒在该对象上等待的所有线程

  • wait()

    wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait方法一直等待,直到获得锁或者被中断。wait(long timeout)设定了一个超时间隔,如果在规定时间没有获得锁就返回。

    调用wait方法后线程进入睡眠状态,直到以下事件发生:

    1. 其他线程调用了该对象的notify/notifyAll方法
    2. 其他线程调用interrupt中断了该线程
    3. 时间间隔到了
  • finalize()

    该方法用于释放资源,当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法

    当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法

判断两个对象是否相等(对象的内容和hashcode必须相等)

1.==和equals区别

  • ==用于判断对象的地址是否相等
  • equals方法也用作判断对象是否相等,有两种情况:
    1. 类没有覆盖equals方法,则当用equals比较该类的两个对象时,相当于调用父类的equals方法,等同于==。
    2. 类覆盖了equals方法,一般会将equals重写成判断两个对象的内容是否相等,如果它们的内容相等,就返回true。

举个例子:

public class Person {
private int age;
public Person(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static void main(String[] args) {
Person p1 = new Person(10);
Person p2 = new Person(10);
String s1 = new String("123");
String s2 = new String("123");
System.out.println(p1 .equals(p2));#false
System.out.println(s1.equals(s2));#true
}
}

解析

  • 虽然Person对象的内容相等,但是未复写equals方法,执行的还是Object中的equals方法,比较的还是地址
  • String中重写了equals方法,比较的是对象的内容

String中equals源码:

public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
//判断对象是否是String类型
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;
}

2.hashcode与equals的关系

hashcode的作用是用来获取哈希码,也称作散列码。返回的类型是int,用于确定对象在hash表中的位置。Object中有hashcode方法,意味着所有的类都有hashcode方法。

为什么在重写equals方法时,需要重写hashcode方法?

为了提高程序的效率才实现hashCode方法,两个对象在进行比较的时候,如果它们的hashCode不相等,那么就没有必要进行equals方法比较了。

举个例子:在集合中,List集合中的元素是有序的,元素可以重复的;set集合是无序的,元素不能重复。那么如何保证集合里的元素是不能重复的,虽然可以使用equals方法,但是效率太低。假如集合里的元素本来有10000个,那么再新增一个元素,如果一个一个比较,那么效率实在太低。这时候就体现hashcode的优势了,java采用hash表,利用哈希算法,就是将对象数据根据该对象的特征使用特定的算法将其定义到一个地址上,那么在后面定义进来的数据,只要看对应的hashcode地址上是否有值,那么就用equals比较,如果没有则直接插入,只要就大大减少了equals的使用次数,执行效率就大大提高了。

样例,重写了equals方法,没有重写hashcode方法:

public class Person {
private int age;
public Person(int age) {
this.age = age;
}
//getter、setter方法略
@Override
public boolean equals(Object obj) {
return true;
}
public static void main(String[] args) {
Person p1 = new Person(10);
Person p2 = new Person(10);
System.out.println("p1:"+p1.hashCode());#p1:1163157884
System.out.println("p2:"+p2.hashCode());#p2:1956725890
System.out.println(p1 .equals(p2));#true HashSet<Object> hashSet = new HashSet<>();
hashSet.add(p1);
hashSet.add(p2);
System.out.println(hashSet);#[Person{age=10}, Person{age=10}]
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}

虽然p1和p2的内容相等,但是我没有重写hashcode方法,所以p1、p2的hashcode不相等;我们知道hashset中不能有相同对象,但是测试用例中竟然有两个同样的Person对象,原因如下:

hashset在添加元素时会做以下判断

  1. 如果添加的元素的hashcode相等并且equals比较时也为true,就认为是同一个元素。
  2. 如果不符合上面的条件,就会认为添加的元素是一个新元素。

样例,简单重写了equals方法和hashcode方法:

public class Person {
private int age;
public Person(int age) {
this.age = age;
}
//getter、setter方法略
@Override
public boolean equals(Object obj) {
return true;
} @Override
public int hashCode() {
return 0;
}
public static void main(String[] args) {
Person p1 = new Person(10);
Person p2 = new Person(10); System.out.println(p1 .equals(p2));# true
System.out.println("p1:"+p1.hashCode());# 0
System.out.println("p2:"+p2.hashCode());# 0
HashSet<Object> hashSet = new HashSet<>();
hashSet.add(p1);
hashSet.add(p2); System.out.println(hashSet);#[Person{age=10}] [Person{age=10}]
} @Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}

从结果看出,p1、p2的内容相等并且hashcode也相等,hashset中只有一个元素。

小结

  • 如果两个对象相等,则hashcode一定也是相同的
  • 两个对象相等,对两个对象分别调用equals方法都返回true
  • 两个对象有相同的hashcode值,它们也不一定是相等的
  • 因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
  • hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

参考

Object有哪些方法

Java中如何判断两个对象是否相等

hashcode和equals

http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html

Object中的方法以及对象相等的判定的更多相关文章

  1. Python_day8_面向对象(多态、成员修饰符、类中特殊方法、对象边缘知识)、异常处理之篇

    一.面向对象之多态 1.多态:简而言子就是多种形态或多种类型 python中不支持多态也用不到多态,多态的概念是应用与java/C#中指定传参的数据类型, java多态传参:必须是传参数的数据类型或传 ...

  2. hashCode -哈希值,Object中的方法,常根据实际情况重写

    package cn.learn.collection; import cn.learn.basic.Phone; /* 哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值),是一个逻辑地址 ...

  3. Object中toString方法

    在Java中,所有的对象都是继承自Object,自然继承了toString方法,在当使用System,out.println()里面为一个对象的引用时,自动调用toString方法将对象打印出来.如果 ...

  4. Java中的equals和==的区别以及几个常用的object中的方法简单的调试方法

    一.equals 1.equals:是Object类中的方法,只能判断引用类型 2.默认判断的是地址是否相等(判断两个参数是否是同一个对象),子类中往往重写该方法,用于判断内容(值)是否相等 二.== ...

  5. tp5依赖注入(自动实例化):解决了像类中的方法传对象的问题

    app\index\Demo1.php namespace app\index\controller; /* 容器与依赖注入的原理 ----------------------------- 1.任何 ...

  6. Object中的方法

    1.equals() 2.toString() package com_package1; public class Person44 { private int age; public int ge ...

  7. 方法object面试题分析:7JAVA中Object的clone方法详解-克隆-深克隆

    时间紧张,先记一笔,后续优化与完善.     每日一道理 翻开早已发黄的页张,试着寻找过去所留下的点点滴滴的足迹.多年前的好友似乎现在看来已变得陌生,匆忙之间,让这维持了多年的友谊变淡,找不出什么亲切 ...

  8. java中equal方法总结

    场景:本周在完成一个公司业务功能时,在判断是否为代叫单时调用了equal方法: PublishOrderType.HELP_ORDER.equals(valetOrderExtraInfoDO.get ...

  9. Java中clone方法的使用

    什么是clone 在实际编程过程中,我们常常要遇到这种情况:有一个对象object1,在某一时刻object1中已经包含了一些有效值,此时可能会需要一个和object1完全相同新对象object2,并 ...

随机推荐

  1. A survey of best practices for RNA-seq data analysis RNA-seq数据分析指南

    A survey of best practices for RNA-seq data analysis RNA-seq数据分析指南 内容 前言 各位同学/老师,大家好,现在由我给大家讲讲我的文献阅读 ...

  2. 模拟在table中移动鼠标,高亮显示鼠标所在行,固定表头

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...

  3. [原创]解决IPCH关闭后可能引发的无法调试的BUG

    前几天清理硬盘,发现大量IPCH目录,文件特别巨大,看着头大,所以决定改为临时模式,同时VS2015和VS2013我都改了,设置如下: (关键字:IPCH目录,VS大文件) 当设置好之后不会出现烦人的 ...

  4. 09 Finding a Motif in DNA

    Problem Given two strings ss and tt, tt is a substring of ss if tt is contained as a contiguous coll ...

  5. openssl生成ssl证书(转)

    原文:http://blog.sina.com.cn/s/blog_4fd50c390101891c.html x509证书一般会用到三类文,key,csr,crt. Key 是私用密钥openssl ...

  6. Swift:超炫的View Controller切换动画

    匿名社交应用Secret的开发者开发了一款叫做Ping的应用,用户可以他们感兴趣的话题的推送. Ping有一个很炫的东西,就是主界面和之间切换的动画做的非常的好.每次看到一个非常炫的动画,都不由得会想 ...

  7. Git config 配置文件

    一.Git已经在你的系统中了,你会做一些事情来客户化你的Git环境.你只需要做这些设置一次:即使你升级了,他们也会绑定到你的环境中.你也可以在任何时刻通过运行命令来重新更改这些设置. Git有一个工具 ...

  8. Python + selenium + unittest装饰器 @classmethod

    前言 前面讲到unittest里面setUp可以在每次执行用例前执行,这样有效的减少了代码量,但是有个弊端,比如打开浏览器操作,每次执行用例时候都会重新打开,这样就会浪费很多时间. 于是就想是不是可以 ...

  9. [C#]如何解决修改注册表受限问题(转)

    在项目中添加一个Application Manifest File,名字默认为app.manifest,内容中应该有一行: <requestedExecutionLevellevel=" ...

  10. .net core redis使用

    整理下.net core的redis使用  可以分布式 Nuget安装 StackExchange.Redis using System; using System.Collections.Gener ...