bra*_*ter 592 java identity equality object-comparison
我想澄清一下我是否理解正确:
==
- >是参考比较,即两个对象都指向相同的内存位置.equals()
- >计算对象中值的比较我的理解是正确的吗?
Hov*_*els 604
一般来说,你的问题的答案是"是",但......
.equals(...)
只会比较它所写的比较,不多也不少.equals(Object o)
覆盖此方法的最近父类的方法.Object#equals(Object o)
方法.根据Object API,它与==
; 也就是说,当且仅当两个变量引用同一个对象时,如果它们的引用是同一个,它才返回true .因此,您将测试对象相等性而不是功能相等性.hashCode
如果你改写equals
,总是记得覆盖,以免"违反合同".根据API,如果hashCode()
两个对象的方法表明它们是等价的,那么从两个对象的方法返回的结果必须相同equals
.反过来并不一定是真的.小智 104
关于String类:
equals()方法比较String实例(在堆上)中的"值",而不管两个对象引用是否引用相同的String实例.如果任何两个String类型的对象引用引用相同的String实例那么太棒了!如果两个对象引用引用两个不同的String实例,则它没有区别.它是正在比较的每个String实例中的"值"(即:字符数组的内容).
另一方面,"==" 运算符比较两个对象引用的值,以查看它们是否引用相同的String实例.如果两个对象引用的值"引用"相同的String实例,则布尔表达式的结果将为"true".. duh.另一方面,如果两个对象引用的值"引用" 不同的String实例(即使两个String实例具有相同的"值",也就是说,每个String实例的字符数组的内容都相同)布尔表达式的结果将为"false".
与任何解释一样,让它沉入其中.
我希望这可以解决一些问题.
Alm*_*pos 58
根据您是在谈论"原语"还是"对象类型",存在一些小差异; 如果你在谈论"静态"或"非静态"成员,也可以这样说; 你也可以混合以上所有......
这是一个例子(你可以运行它):
public final class MyEqualityTest
{
public static void main( String args[] )
{
String s1 = new String( "Test" );
String s2 = new String( "Test" );
System.out.println( "\n1 - PRIMITIVES ");
System.out.println( s1 == s2 ); // false
System.out.println( s1.equals( s2 )); // true
A a1 = new A();
A a2 = new A();
System.out.println( "\n2 - OBJECT TYPES / STATIC VARIABLE" );
System.out.println( a1 == a2 ); // false
System.out.println( a1.s == a2.s ); // true
System.out.println( a1.s.equals( a2.s ) ); // true
B b1 = new B();
B b2 = new B();
System.out.println( "\n3 - OBJECT TYPES / NON-STATIC VARIABLE" );
System.out.println( b1 == b2 ); // false
System.out.println( b1.getS() == b2.getS() ); // false
System.out.println( b1.getS().equals( b2.getS() ) ); // true
}
}
final class A
{
// static
public static String s;
A()
{
this.s = new String( "aTest" );
}
}
final class B
{
private String s;
B()
{
this.s = new String( "aTest" );
}
public String getS()
{
return s;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过以下链接比较"=="(Equality Operator)和".equals(...)"(java.lang.Object类中的方法)的解释:
gov*_*tel 44
==和equals之间的区别让我困惑了一段时间,直到我决定仔细看看它.他们中的许多人说比较字符串你应该使用equals
和不使用==
.希望在这个答案中我能够说出不同之处.
回答这个问题的最好方法是向自己提出几个问题.让我们开始吧:
以下程序的输出是什么:
String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);
Run Code Online (Sandbox Code Playgroud)
如果你说,
false
true
Run Code Online (Sandbox Code Playgroud)
我会说你是对的,但你为什么这么说呢?如果你说输出是,
true
false
Run Code Online (Sandbox Code Playgroud)
我会说你错了,但我仍会问你,为什么你认为这是对的?
好的,让我们试着回答这个:
以下程序的输出是什么:
String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);
Run Code Online (Sandbox Code Playgroud)
现在如果你说,
false
true
Run Code Online (Sandbox Code Playgroud)
我会说你错了,但为什么现在错了?该程序的正确输出是
true
false
Run Code Online (Sandbox Code Playgroud)
请比较上面的程序,并尝试考虑它.
好.现在这可能有所帮助(请阅读:打印对象的地址 - 不可能,但我们仍然可以使用它.)
String mango = "mango";
String mango2 = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(mango3 != mango2);
System.out.println(mango3 == mango2);
// mango2 = "mang";
System.out.println(mango+" "+ mango2);
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(System.identityHashCode(mango));
System.out.println(System.identityHashCode(mango2));
System.out.println(System.identityHashCode(mango3));
Run Code Online (Sandbox Code Playgroud)
你可以尝试考虑上面代码中最后三行的输出:对我来说,意思是打印出来的(你可以在这里查看代码):
false
true
true
false
mango mango
false
true
17225372
17225372
5433634
Run Code Online (Sandbox Code Playgroud)
哦! 现在你看到identityHashCode(mango)等于identityHashCode(mango2)但是它不等于identityHashCode(mango3)
尽管所有字符串变量 - 芒果,芒果2和芒果3 - 具有相同的值,即"芒果",identityHashCode()
但对所有人来说仍然不一样.
现在尝试取消注释这一行// mango2 = "mang";
并再次运行它,这次你将看到所有三个identityHashCode()
都不同.嗯这是一个有用的提示
我们知道if hashcode(x)=N
和hashcode(y)=N
=>x is equal to y
我不确定java内部是如何工作的,但我认为这就是我说的时候发生的事情:
mango = "mango";
Run Code Online (Sandbox Code Playgroud)
Java的创建一个字符串,"mango"
它指出(参考)由变量mango
是这样的
mango ----> "mango"
Run Code Online (Sandbox Code Playgroud)
现在在下一行我说:
mango2 = "mango";
Run Code Online (Sandbox Code Playgroud)
它实际上重用了"mango"
看起来像这样的字符串
mango ----> "mango" <---- mango2
Run Code Online (Sandbox Code Playgroud)
芒果和芒果2指向相同的参考现在,当我说
mango3 = new String("mango")
Run Code Online (Sandbox Code Playgroud)
它实际上为"芒果"创建了一个全新的引用(字符串).看起来像这样,
mango -----> "mango" <------ mango2
mango3 ------> "mango"
Run Code Online (Sandbox Code Playgroud)
这就是为什么当我推出它的价值时mango == mango2
,它就推出了true
.当我拿出它的值时mango3 == mango2
,它就会被推出false
(即使值相同).
当你取消注释该行// mango2 = "mang";
它实际上创建了一个字符串"mang",它将我们的图形转换为:
mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"
Run Code Online (Sandbox Code Playgroud)
这就是为什么identityHashCode对所有人都不一样.
希望这可以帮助你们.实际上,我想生成一个测试用例,其中==失败并且equals()通过.如果我错了,请随时发表评论并告诉我.
dhe*_*ran 29
在==操作符测试两个变量是否有相同的引用(又名指向一个内存地址).
String foo = new String("abc");
String bar = new String("abc");
if(foo==bar)
// False (The objects are not the same)
bar = foo;
if(foo==bar)
// True (Now the objects are the same)
Run Code Online (Sandbox Code Playgroud)
而equals()方法测试两个变量是否引用具有相同状态(值)的对象.
String foo = new String("abc");
String bar = new String("abc");
if(foo.equals(bar))
// True (The objects are identical but not same)
Run Code Online (Sandbox Code Playgroud)
干杯:-)
如果不覆盖.equals(),==和.equals()都指向同一个对象.
一旦你覆盖.equals(),你希望你想做什么.您可以将调用对象的状态与传入的对象的状态进行比较,也可以调用super.equals()
==运算符:
==是Java中的关系运算符,用于比较两个操作数。它用于确定两个操作数是否相等。使用==运算符,可以比较任何原始类型,例如int,char,float和Boolean。比较之后,==运算符返回一个布尔值。如果两个操作数相等,则==运算符将返回一个真值。但是,如果两个操作数不相等,则返回错误值。当与对象一起使用时,==运算符将比较两个对象引用,并确定它们是否引用同一实例。
.equals()方法
equals()是String类中可用的方法,用于比较两个字符串并确定它们是否相等。作为比较的结果,此方法返回布尔值。如果两个字符串包含相同顺序的相同字符,则equals()方法返回true。否则,它返回一个假值。
relational operator ==
以下是区分和之间的一般规则the method .equals()
。
object1 == object2
比较 object1 和 object2 引用的对象是否引用Heap 中的同一内存位置。
object1.equals(object2)
比较object1 和 object2 的值,无论它们位于内存中的哪个位置。
使用 String 可以很好地证明这一点
场景1
public class Conditionals {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = new String("Hello");
System.out.println("is str1 == str2 ? " + (str1 == str2 ));
System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
}
}
The result is
is str1 == str2 ? false
is str1.equals(str2) ? true
Run Code Online (Sandbox Code Playgroud)
场景2
public class Conditionals {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
System.out.println("is str1 == str2 ? " + (str1 == str2 ));
System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
}
}
The result is
is str1 == str2 ? true
is str1.equals(str2) ? true
Run Code Online (Sandbox Code Playgroud)
该字符串比较可以用作比较其他类型对象的基础。
例如,如果我有一个 Person 类,我需要定义比较两个人的标准。假设这个 person 类有身高和体重的实例变量。
因此,创建 person 对象person1 and person2
并使用这两个对象进行比较,.equals()
我需要重写person 类的 equals 方法来定义基于哪些实例变量(身高或体重)进行比较。
但是,那== operator will still return results based on the memory location of the two objects(person1 and person2)
。
为了便于概括此人对象比较,我创建了以下测试类。对这些概念进行实验将揭示大量事实。
package com.tadtab.CS5044;
public class Person {
private double height;
private double weight;
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(height);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
/**
* This method uses the height as a means of comparing person objects.
* NOTE: weight is not part of the comparison criteria
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (Double.doubleToLongBits(height) != Double.doubleToLongBits(other.height))
return false;
return true;
}
public static void main(String[] args) {
Person person1 = new Person();
person1.setHeight(5.50);
person1.setWeight(140.00);
Person person2 = new Person();
person2.setHeight(5.70);
person2.setWeight(160.00);
Person person3 = new Person();
person3 = person2;
Person person4 = new Person();
person4.setHeight(5.70);
Person person5 = new Person();
person5.setWeight(160.00);
System.out.println("is person1 == person2 ? " + (person1 == person2)); // false;
System.out.println("is person2 == person3 ? " + (person2 == person3)); // true
//this is because perosn3 and person to refer to the one person object in memory. They are aliases;
System.out.println("is person2.equals(person3) ? " + (person2.equals(person3))); // true;
System.out.println("is person2.equals(person4) ? " + (person2.equals(person4))); // true;
// even if the person2 and person5 have the same weight, they are not equal.
// it is because their height is different
System.out.println("is person2.equals(person4) ? " + (person2.equals(person5))); // false;
}
}
Run Code Online (Sandbox Code Playgroud)
该类的执行结果为:
is person1 == person2 ? false
is person2 == person3 ? true
is person2.equals(person3) ? true
is person2.equals(person4) ? true
is person2.equals(person4) ? false
Run Code Online (Sandbox Code Playgroud)
请记住,.equals(...)
必须由您要比较的类实现.否则,没有太大意义; Object类的方法版本与比较操作的作用相同:Object#equals.
您真正想要使用对象的比较运算符的唯一时间是您要比较枚举.这是因为一次只有一个枚举值的实例.例如,鉴于枚举
enum FooEnum {A, B, C}
Run Code Online (Sandbox Code Playgroud)
你永远不会有多个实例A
,而且B
和C
.这意味着您实际上可以编写如下方法:
public boolean compareFoos(FooEnum x, FooEnum y)
{
return (x == y);
}
Run Code Online (Sandbox Code Playgroud)
而且你没有任何问题.
String w1 ="Sarat";
String w2 ="Sarat";
String w3 = new String("Sarat");
System.out.println(w1.hashCode()); //3254818
System.out.println(w2.hashCode()); //3254818
System.out.println(w3.hashCode()); //3254818
System.out.println(System.identityHashCode(w1)); //prints 705927765
System.out.println(System.identityHashCode(w2)); //prints 705927765
System.out.println(System.identityHashCode(w3)); //prints 366712642
if(w1==w2) // (705927765==705927765)
{
System.out.println("true");
}
else
{
System.out.println("false");
}
//prints true
if(w2==w3) // (705927765==366712642)
{
System.out.println("true");
}
else
{
System.out.println("false");
}
//prints false
if(w2.equals(w3)) // (Content of 705927765== Content of 366712642)
{
System.out.println("true");
}
else
{
System.out.println("false");
}
//prints true
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
615631 次 |
最近记录: |