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,并 ...
随机推荐
- JAVA中取余(%)规则和介绍
在java中%的含义为取余. java :a%b 数学公式a%b=a-(a/b)*b
- ASCII表
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧 ...
- [UCSD白板题 ]Small Fibonacci Number
Problem Introduction The Fibonacci numbers are defined as follows: \(F_0=0\), \(F_1=1\),and \(F_i=F_ ...
- HDU 4089 Activation(概率DP)(转)
11年北京现场赛的题目.概率DP. 公式化简起来比较困难....而且就算结果做出来了,没有考虑特殊情况照样会WA到死的.... 去参加区域赛一定要考虑到各种情况. 像概率dp,公式推出来就很容易写 ...
- C++ —— 编译程序
目录: 0.GCC online documentation 1.gcc编译器 常用命令 2.VC编译器 常用参数说明 3.C预处理器命令说明 4.debug 和 release 的区别 0.GCC ...
- 最简单实用的JQuery实现banner图中的text打字动画效果!!!
下面,就让小博详细介绍如何实现上面GIF实现的banner图中的文字动画效果,最简单实用的方法(鉴于代码量较小,就内嵌在一个HTML文件中了): 首先,我们要在header导入一个jQuery,并新建 ...
- PyQt5多点触控写字板实现及困惑
Qt支持程序多点触控,就想使用PyQt5做一个触控画板,经过几番周折,查阅了TouchEvent官方文档,又参考了一篇QT for Android的例子,采用eventfilter过滤器来识别触屏事件 ...
- KMP总结
首先给一个我能看懂的KMP讲解: http://blog.csdn.net/v_july_v/article/details/7041827 来自大神july 文章很长,但是慢慢看,会发现讲的很好. ...
- python3读取MySQL-Front的MYSQL密码
python3读取MySQL-Front的MYSQL密码 python3 mysql 密码 MySQL-Front 前言 同样的套路又来了,继续尝试从配置文件中读取敏感的信息,这次轮到的是MySQL- ...
- javaweb之Filter过滤器详解
快速入门 1.新建一个类,实现Filter接口 2.实现doFilter()方法,打印一句话,来证明能够进行拦截 3.在web.xml中进行配置(参照Servlet配置) 4.访问一个页面,看看能不能 ...