Object中的方法以及对象相等的判定
看图说话

Object有以下几个方法
getClass()
final类型,主要是用来获得运行时的类型
hashCode()
返回该对象的哈希码值,方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。该方法常用于hash查找,重写equals方法一般都要重写hashCode方法
equals()
equals方法一般和==是不一样的,但是在Object中,两者一样。子类一般都要重写这个方法
clone()
创建并返回对象的副本,它实现对象的浅复制
toString()
返回对象的字符串表示
notify()
唤醒在该对象上等待的某个线程
notifyAll()
唤醒在该对象上等待的所有线程
wait()
wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait方法一直等待,直到获得锁或者被中断。wait(long timeout)设定了一个超时间隔,如果在规定时间没有获得锁就返回。
调用wait方法后线程进入睡眠状态,直到以下事件发生:
- 其他线程调用了该对象的notify/notifyAll方法
- 其他线程调用interrupt中断了该线程
- 时间间隔到了
finalize()
该方法用于释放资源,当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法
判断两个对象是否相等(对象的内容和hashcode必须相等)
1.==和equals区别
- ==用于判断对象的地址是否相等
- equals方法也用作判断对象是否相等,有两种情况:
- 类没有覆盖equals方法,则当用equals比较该类的两个对象时,相当于调用父类的equals方法,等同于==。
- 类覆盖了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在添加元素时会做以下判断
- 如果添加的元素的hashcode相等并且equals比较时也为true,就认为是同一个元素。
- 如果不符合上面的条件,就会认为添加的元素是一个新元素。
样例,简单重写了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 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
参考
http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html
Object中的方法以及对象相等的判定的更多相关文章
- Python_day8_面向对象(多态、成员修饰符、类中特殊方法、对象边缘知识)、异常处理之篇
一.面向对象之多态 1.多态:简而言子就是多种形态或多种类型 python中不支持多态也用不到多态,多态的概念是应用与java/C#中指定传参的数据类型, java多态传参:必须是传参数的数据类型或传 ...
- hashCode -哈希值,Object中的方法,常根据实际情况重写
package cn.learn.collection; import cn.learn.basic.Phone; /* 哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值),是一个逻辑地址 ...
- Object中toString方法
在Java中,所有的对象都是继承自Object,自然继承了toString方法,在当使用System,out.println()里面为一个对象的引用时,自动调用toString方法将对象打印出来.如果 ...
- Java中的equals和==的区别以及几个常用的object中的方法简单的调试方法
一.equals 1.equals:是Object类中的方法,只能判断引用类型 2.默认判断的是地址是否相等(判断两个参数是否是同一个对象),子类中往往重写该方法,用于判断内容(值)是否相等 二.== ...
- tp5依赖注入(自动实例化):解决了像类中的方法传对象的问题
app\index\Demo1.php namespace app\index\controller; /* 容器与依赖注入的原理 ----------------------------- 1.任何 ...
- Object中的方法
1.equals() 2.toString() package com_package1; public class Person44 { private int age; public int ge ...
- 方法object面试题分析:7JAVA中Object的clone方法详解-克隆-深克隆
时间紧张,先记一笔,后续优化与完善. 每日一道理 翻开早已发黄的页张,试着寻找过去所留下的点点滴滴的足迹.多年前的好友似乎现在看来已变得陌生,匆忙之间,让这维持了多年的友谊变淡,找不出什么亲切 ...
- java中equal方法总结
场景:本周在完成一个公司业务功能时,在判断是否为代叫单时调用了equal方法: PublishOrderType.HELP_ORDER.equals(valetOrderExtraInfoDO.get ...
- Java中clone方法的使用
什么是clone 在实际编程过程中,我们常常要遇到这种情况:有一个对象object1,在某一时刻object1中已经包含了一些有效值,此时可能会需要一个和object1完全相同新对象object2,并 ...
随机推荐
- JavaScript 分号使用总结
没有应该不应该,只有你自己喜欢不喜欢.JavaScript 语法长得 C-like 不代表它本质上和 C 是一类语言,所有直觉性的 "当然应该加分号" 都是保守的.未经深入思考的草 ...
- 全球数据库-->基金/管理产品-->基金分析/新闻/报告
加拿大共同基金 澳大利亚投资信托 美国ETF 美国共同基金 英国投资信托基金 名称 分析师名称 分析日期 晨星分析师评级 晨星简报
- 网络爬虫--requests库中两个重要的对象
当我们使用resquests.get()时,返回的时response的对象,他包含服务器返回的所有信息,也包含请求的request的信息. 首先: response对象的属性有以下几个, r.stat ...
- SQLServer函数 left()、charindex()、stuff()的使用
1.left() LEFT (<character_expression>, <integer_expression>) 返回character_expression 左起 ...
- chrome会话cookie显示过期时间为1969-12-31T23:59:59.000Z
cookie不设置过期时间的话,为浏览器会话cookie,关闭浏览器自动删除cookie 但是在chrome浏览器下,cookie过期时间显示为“1969-12-31T23:59:59.000Z” 在 ...
- lnmp 一键安装包 nginx配置tp5 phpinfo模式 隐藏index.php
tp5 url 线上访问 在nginx 上 出现404错误 那是因为pathinfo没有被支持 修改如下:找到 /usr/local/nginx/config/vhost/项目名.config s ...
- RocketMQ 服务器3模式
22 a b-s---------------------------sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-a.propertie ...
- <网络攻防实践> 课程总结20169216
课程总结20169216 每周作业链接汇总 第一周作业:Linux基础入门(1-5).基本概念及操作 第二周作业:linux基础入门(6-11).网络攻防技术概述网络攻防试验环境搭构.Kali教学视频 ...
- 如何在Mirth Connect中创建和调用自定义Java代码
0-前言 本文章将向您展示如何创建自定义Java类,将其编译/打包到JAR中,将其包含在Mirth Connect在,并在JavaScript中调用它,您可以从任何JavaScript上下文调用自定义 ...
- CentOS6.3安装MySQL5.5
1.查看系统是否安装了MySQL 使用命令: #rpm -qa | grep mysql 2.卸载已安装的MySQL 卸载mysql命令如下: #rpm -e --nodeps mysql-libs ...