Java程序中测试两个变量时否相等有两种方法: == 和 equals。

==判断

当使用==来判断两个变量是否相等时,如果两个变量是基本类型变量,且都是数字类型(不一定要求数据类型严格相同),则只要两个变量的值相同,就将返回true。
但对于两个引用类型变量,只有它们指向同一个对象时,== 判断才会返回true。
== 不可用于比较类型上没有父子关系的两个变量。

public static void main(String[] args) {
int i = 65;
float f = 65.0f;
// 输出true
System.out.println("65和65.0f是否相等?" + (i == f)); char c = 'A';
// 输出true
System.out.println("65和'A'是否相等?" + (i == c)); String s1 = new String("Test");
String s2 = new String("Test");
// 输出false
System.out.println("s1和s2是否相等?" + (s1 == s2));
// 输出true
System.out.println("s1和s2是否相等?" + (s1.equals(s2))); // 编译不过
// System.out.println("Test" == new EqualTest());
}

需要注意 "Test"和new String("Test")是有区别的?

  “Test”是字符串直接量(即可以在编译时就计算出来的字符串值),JVM使用常量池来管理这些字符串,

  当使用new String("Test")时,JVM先使用常量池来管理“Test”直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象被保存在堆内存中。也就是说new String("Test")一共创建了两个字符串对象。

常量池(constant pool)专门用来管理在编译时被确定并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口中的常量,还包括字符串常量。

public static void main(String[] args) {
String s1 = "Hello";
String s2 = "H";
String s3 = "ello";
// 不能在编译时确定
String s4 = s2 + s3;
// 在编译时就确定下来了,直接引用常量池中的“Hello”
String s5 = "H" + "ello";
// 引用内存中新创建的String对象
String s6 = new String("Hello"); // true
System.out.println(s1 == s5); // false
System.out.println(s1 == s4); // false
System.out.println(s1 == s6);
}

equals判断

equals()方法是Object类提供的一个实例方法,因此所有的引用变量都可以调用该方法来判断是否与其他引用变量相等。

判断两个对象相等时,和==运算符没有区别,同样要求两个引用变量指向同一个对象才返回true。因此Object提供的equals方法没有太大的意义,可以重写equals()方法实现。

注意,String已经重写了equals()方法,只要两个字符串所包含的字符串序列相同,则返回true。

笼统的说equals()方法是判断两个对象的值相等,这样的说法并不准确。

public class EqualsTest {
public static void main(String[] args) {
Person p1 = new Person("小王", "1234");
Person p2 = new Person("王二", "1234");
Person p3 = new Person("小王", "12345"); // true
System.out.println(p1.equals(p2));
// false
System.out.println(p1.equals(p3));
}
} class Person {
private String name;
private String idStr; public Person() { } public Person(String name, String idStr) {
this.name = name;
this.idStr = idStr;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getIdStr() {
return idStr;
} public void setIdStr(String idStr) {
this.idStr = idStr;
} // 重写equals方法,自定义两个对象相等的条件
public boolean equals(Object obj) {
// 如果两个对象是同一个对象
if (this == obj) {
return true;
} // 只有当obj对象是Person对象
if (obj != null && obj.getClass() == Person.class) {
Person personObj = (Person) obj;
// 并且当前对象的idStr和obj对象的idStr相等时,才判断两个对象相等
if (this.getIdStr().equals(personObj.getIdStr())) {
return true;
}
} return false;
}
}

正确的重写equals()方法,应该满足下列条件:

1. 自反性:对任意的x,x.equals(x)一定返回true。

2. 对称性:对任意x, y,如果x.equals(y)返回true,则y.equals(x)返回true。

3. 传递性:对任意x, y, z,如果x.equals(y)返回true,y.equals(x)返回true,则x.equals(z)也返回true。

4. 一致性:对任意x, y,如果对象中用于等价比较的信息没有改变,那么无论x.equals(y)多少次,返回的结果应该保持一致,要么一直是true,一直是false。

5. 对任何不是null的x, x.equals(null)一定返回false。

Object默认提供的equals()只是比较对象的地址,即Object类的equals()方法比较的结果与==运算符比较的结果完全相同。因此,在实际应用中常常需要重写equals()方法,相等的条件是由业务要求决定,因此equals()方法的实现也是由业务要求决定。

==和equals方法的更多相关文章

  1. List<T>Find方法,FindAll方法,Contains方法,Equals方法

    假如传入的T是一个类, List<MessageInfos> MessageInfos = new List<MessageInfos>(); MessageInfos= Me ...

  2. [java] 更好的书写equals方法-汇率换算器的实现(4)

    [java] 更好的书写equals方法-汇率换算器的实现(4) // */ // ]]>   [java] 更好的书写equals方法-汇率换算器的实现(4) Table of Content ...

  3. java中的equals()方法重写

    如何java中默认的equals方法跟实际不符的话,需要重写equals方法.例如: public class TestEquals { public static void main(String[ ...

  4. java提高篇(十三)-----equals()方法总结

    equals() 超类Object中有这个equals()方法,该方法主要用于比较两个对象是否相等.该方法的源码如下: public boolean equals(Object obj) { retu ...

  5. Java中“==”与equals方法的区别

    1. 用“==”比较两个变量,如果两个变量是基本类型变量,且都是数值类,则值相等就返回true 如果两个变量是引用型变量,则两个对象的地址一样,即指向同一个对象,则返回true 2.equals:St ...

  6. equals()方法

    equals()方法是根类Object中的一个方法,子类可以根据需要重写该方法(比如:String类). 一.Object类中的equals()方法实现如下: public boolean equal ...

  7. C#中==与Equals方法的区别

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace Console ...

  8. java重写equals方法

    @Override public int hashCode() { return task.getId(); } @Override public boolean equals(Object obj) ...

  9. 重写Object类中的equals方法

    Object是所有类的父亲,这个类有很多方法,我们都可以直接调用,但有些方法并不适合,例如下面的student类 public class Student { //姓名.学号.年纪 private S ...

  10. java中hashCode方法与equals方法的用法总结

    首先,想要明白hashCode的作用,必须要先知道Java中的集合. 总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重 ...

随机推荐

  1. 《CSS权威指南(第三版)》---第一章 CSS和文档

    主要学习的知识是怎么把CSS和HTML文档关联: 1.这是默认的样式表 <link rel="stylesheet" href="" type=" ...

  2. 分享知识-快乐自己:Hibernate 中 get() 和 load()、sava、update、savaOrUpdate、merge,不同之处及执行原理?

    1):Hibernate 中 get()  和 load() 有什么不同之处? 1)Hibernate的 get方法,会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在缓存中查 ...

  3. 基于深度学习的安卓恶意应用检测----------android manfest.xml + run time opcode, use 深度置信网络(DBN)

    基于深度学习的安卓恶意应用检测 from:http://www.xml-data.org/JSJYY/2017-6-1650.htm 苏志达, 祝跃飞, 刘龙     摘要: 针对传统安卓恶意程序检测 ...

  4. 【坑坑坑坑坑】fwrite没有把数据写到文件中???

    原文:https://blog.csdn.net/kuaidfkuai/article/details/45918025 <unix环境高级编程>中介绍标准IO: 标准IO流操作读写普通文 ...

  5. JavaScript里值比较的方法

    JavaScript里值比较的方法 参考资料 一张图彻底搞懂JavaScript的==运算 toString()和valueof()方法的区别 Object.is 和 == 与 === 不同 == 运 ...

  6. PS 滤镜— —图像偏移

    clc; clear all; close all; addpath('E:\PhotoShop Algortihm\Image Processing\PS Algorithm'); I=imread ...

  7. kettle结合MySQL生成保留最近6个月月度报告_20161009

    之前计算用户ID各月的金额(各月在列字段),用的是下面代码 ,b.金额,,b.金额,,b.金额,NULL)) AS 9月金额 FROM ( SELECT city AS 城市,DATE_FORMAT( ...

  8. poj3017 Cut the Sequence[平衡树+单调队列优化]

    这里已经讲得很清楚了. 本質上是決策點與區間最大值有一定關係,於是用单调队列来维护决策集合(而不是常规的),然后在决策集合中选取最小值. 然后觉得这题方法还是很重要的.没写平衡树,用优先队列(堆)来维 ...

  9. 闪回之 Flashback Data Archive

    背景:Oracle 11g 中 Flashback Data Archive 特性.将变化数据另外存储到创建的闪回归档区(Flashback Archive)中,以和 undo 区别开来,这样就可以为 ...

  10. 三台主机搭建LAMP(apache、mariadb、php)

    实验环境:均是CentOS7 httpd:172.16.254.88   2.4.6 PHP:172.16.250.140 5.4.16 mariadb:172.16.250.94 5.5.52 第三 ...