Java,==和equals之间的区别是什么

时间:2017-06-19 06:32:10

标签: java arrays

所以我看过很多文章说这是一个参考比较,即两个对象指向相同的内存位置.equals()评估对象中值的比较

但我不明白这意味着什么,因为当我尝试理解以下代码时,打印的字符串是"不同"和"不一样"。怎么可能? .equals是什么意思?我理解这一切都错了吗?我认为答案是"不同"和"相同"?

import java.util.Arrays;

public class HelloWorld {

    public static void main(String[] args) {
       int arr1[] = {1, 2, 3};
       int arr2[] = {1, 2, 3};
       if (arr1 == arr2){
           System.out.println("Same");
       } else {
           System.out.println("Different");
       }
       if (arr1.equals(arr2)){
           System.out.println("Same");}
       } else {
           System.out.println("Not same");
       }
    }
}

4 个答案:

答案 0 :(得分:4)

是的,带有对象的==是参考比较*(检查操作数是否是对相同对象的引用),而equals是涉及的类定义它的任何内容表示(在equals记录的要求范围内)。有些类将equals定义为与==相同,包括Java的数组。 (因为他们不会覆盖使用==的{​​{3}}的默认实施。)

如果要根据内容的相等性比较Java数组,请改用Object.equals

如果您以有用的方式使用定义equals的类,那么您的实验将会有效,您只是不幸的选择数组。在JVM中找到一个用于此实验的类有点棘手,因为很多人要么不实现equals(比如数组),要么因为有几个不可变的类而混淆可能会重复使用实例(尽管如果您明确使用new则不会;但我不想让您使用new一些您可能不应该使用的内容,例如{ {1}};更多关于Arrays.equals)。我会放弃选择一个好的例子并使用略显旧的班级String

SimpleDateFormat

输出

== Different
equals Same

因为DateFormat a = new SimpleDateFormat("yyyy-MM-dd"); DateFormat b = new SimpleDateFormat("yyyy-MM-dd"); System.out.println(a == b ? "== Same" : "== Different"); System.out.println(a.equals(b) ? "equals Same" : "equals Different"); 定义SimpleDateFormat来检查另一个对象是否也是具有相同格式的equals

here

重新评论这个问题:

  

我有一个答案点,但我只得到==部分,如果.equals正在检查内容,代码怎么没有打印"相同"对于第二个如果

由于SimpleDateFormat ,因此必须检查内容。只有在类重写默认equals(仅使用Object.equals)并实现内容检查时才会这样做。数组不是。 (有人可能会说他们应该有,但他们不会。)其他课程,例如==SimpleDateFormat以及StringInteger

实质上:HashMap始终是参考比较。 ==可能是也可能不是内容比较,具体取决于您使用它的课程。

例如,假设我们有这个类:

equals

由于该课程不会覆盖class Example1 { private int content; Example1(int content) { this.content = content; } public static void main (String[] args) throws java.lang.Exception { Example1 a = new Example1(42); Example1 b = new Example1(42); System.out.println(a == b ? "== Same" : "== Different"); System.out.println(a.equals(b) ? "equals Same" : "equals Different"); } } ,因此您equals==会得到相同的答案("不同") 。 Live example

但是如果我们覆盖equals来定义两个实例相等的意义(在这种情况下:因为它们具有相同的内容):

equals

现在class Example2 { private int content; Example2(int content) { this.content = content; } @Override public boolean equals(Object obj) { if (obj == null || !obj.getClass().equals(this.getClass())) { return false; } Example2 other = (Example2)obj; return this.content == other.content; } @Override public int hashCode() { return this.content; } public static void main (String[] args) throws java.lang.Exception { Example2 a = new Example2(42); Example2 b = new Example2(42); System.out.println(a == b ? "== Same" : "== Different"); System.out.println(a.equals(b) ? "equals Same" : "equals Different"); } } 表示具有相同内容的两个实例是相同的,因为该类定义了这意味着什么。 Live Example。 (另请注意,当覆盖equals时,必须覆盖equals,这就是我上面这样做的原因。)

*更一般地说,hashCode测试其操作数的值是否相同。引用类型的值是一个对象引用,当引用同一个对象时,两个对象引用值只是相同,只有当它们引用不同的对象时才会有所不同(或者其中一个是== ;根本不是指对象。

答案 1 :(得分:0)

要创建对象,您需要一些内存来存储它。

运算符==检查两个变量是否指向同一个内存块。那就是他们指向相同的对象实例(他们是不同别名下的一个人)。

equals()是一种方法,通过某种算法检查相等性。意思是两个对象包含相同的数据(它们是不同的人,但具有相同的面,例如双胞胎)。 java.lang.Object#equals的默认实现是

public boolean equals(Object obj) {
    return (this == obj);
}

使用IDE,您可以确保数组的equals实际为java.lang.Object#equals。要检查两个数组是否相等,您应该使用Arrays.equals。它还有许多其他有用的方法来操作数组。当您需要对数组执行某些操作时,最好先检查此类。它节省了大量时间和代码行。

<强> EDITED

数组(int[], float[], String[], AnyClass[])未实现自定义equals方法。因此,对于数组以及任何自定义类equals()==执行相同的操作,除非您覆盖equals()并提供自定义比较。像

public class Person {
    public String name;
    public String surname;

    public Person(String name, String surname) {
        this.name = name;
        this.surname = surname;
    }

    public boolean equals(Object thatObj) {
        if (thatObj instanceof Person) {
            Person that = (Person) thatObj;
            return this.name.equals(that.name) &&
                this.surname.equals(that.surname);
        }
        return false;
    }
}

答案 2 :(得分:0)

我总是使用以下示例来了解==.equals之间的差异,

String s1 = new String( "Test" );
String s2 = new String( "Test" );

System.out.println( s1 == s2 ); // will print 'false'
System.out.println( s1.equals( s2 )); //  will print 'true'

由于new关键字始终创建新的新对象,因此它将具有2个不同的引用。因此,==比较将返回false。发生这种情况是因为它正在比较参考值(或者有人可以说内存位置值)只有哪些不同。但是,如果你初始化像下面这样的东西(自动装箱),

String s1 = "Test";
String s2 = "Test";

System.out.println( s1 == s2 ); // will print 'true'
System.out.println( s1.equals( s2 )); //  will print 'true'

现在s1s2都将使用相同的对象和相同的引用。

答案 3 :(得分:-1)

==比较参考。在你的例子中,当你创建变量arr1 []它在内存中创建并在内存中拥有它自己的地址时所以当你创建另一个变量arr2 []时它在内存中创建但是有另一个地址所以当你比较时arr1地址不等于arr2地址。但是当你使用.equal时它不会比较记忆位置,而是比较里面的值。 如果你想arr1到arr2 ==彼此必须是这样的:

arr1[] = [1,2,3] arr2[] = arr1;

然后arr1 == arr2 // true