Eu queria esclarecer se entendi isso corretamente:
==
é uma comparação de referência, ou seja, os dois objetos apontam para o mesmo local de memória.equals()
avalia para a comparação de valores nos objetos
.equals()
que isso é equivalente
Eu queria esclarecer se entendi isso corretamente:
==
é uma comparação de referência, ou seja, os dois objetos apontam para o mesmo local de memória.equals()
avalia para a comparação de valores nos objetos.equals()
que isso é equivalente
Respostas:
Em geral, a resposta para sua pergunta é "sim", mas ...
.equals(...)
só comparará o que está escrito para comparar, nem mais, nem menos.equals(Object o)
método da classe pai mais próxima que substituiu esse método.Object#equals(Object o)
método. De acordo com a API de objetos, é o mesmo que ==
; isto é, retornará true se e somente se as duas variáveis se referirem ao mesmo objeto, se suas referências forem uma e a mesma. Assim, você testará a igualdade de objetos e não a funcional .hashCode
se sempre de substituir se você substituir equals
para não "quebrar o contrato". De acordo com a API, o resultado retornado do hashCode()
método para dois objetos deve ser o mesmo se seus equals
métodos mostrarem que são equivalentes. O inverso não é necessariamente verdadeiro.==
verifica a referência de memória, por que estou recebendo esse comportamento estranho em [this] [1] [1]: docs.google.com/document/d/… Esperava que a saída fosse verdadeira. pode limpar minhas confusões
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
<br/> Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
( docs.oracle.com/javase/7/docs/api/java/lang/… )
Com relação à classe String:
O método equals () compara o "valor" dentro das instâncias de String (na pilha), independentemente se as duas referências de objeto se referirem à mesma instância de String ou não. Se quaisquer duas referências de objeto do tipo String se referirem à mesma instância de String, então ótimo! Se as duas referências de objeto se referirem a duas instâncias diferentes de String ... isso não faz diferença. É o "valor" (ou seja: o conteúdo da matriz de caracteres) dentro de cada instância String que está sendo comparada.
Por outro lado, o operador "==" compara o valor de duas referências a objetos para verificar se elas se referem à mesma instância String . Se o valor das duas referências de objeto "se referirem" à mesma instância String, o resultado da expressão booleana seria "true" .. duh. Se, por outro lado, o valor de ambas as referências a objetos "se referirem" a diferentes instâncias de String (mesmo que ambas as instâncias tenham "valores" idênticos, ou seja, o conteúdo das matrizes de caracteres de cada instância de String é o mesmo), O resultado da expressão booleana seria "false".
Como em qualquer explicação, deixe-a afundar.
Espero que isso esclareça um pouco as coisas.
String
s, também ==
é igual a referência, sim, mas geralmente funciona (como em dois String
s com o mesmo conteúdo geralmente será ==
um para o outro), devido à maneira como o Java lida com String
s. Nem sempre, e certamente é uma prática ruim, mas é um erro comum, principalmente de pessoas provenientes de outros idiomas.
String
build from string literal será adicionado a algo chamado de String constant pool
, por exemplo, String s1 = "someString"; String s2 = "someString;"
ambos s1
& s2
compartilharão a mesma referência. s1 == s2
retornará verdadeiro. Mas se eles foram construídos via String constructor
, por exemplo String s1 = new String("someString"); String s2 = new String("someString");
, eles não compartilharão a mesma referência. s1 == s2
retornará falso.
Existem algumas pequenas diferenças, dependendo se você está falando de "primitivas" ou "Tipos de objetos"; o mesmo pode ser dito se você estiver falando sobre membros "estáticos" ou "não estáticos"; você também pode misturar todos os itens acima ...
Aqui está um exemplo (você pode executá-lo):
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;
}
}
Você pode comparar as explicações para "==" (Operador de igualdade) e ".equals (...)" (método na classe java.lang.Object) através destes links:
A diferença entre == e igual me confundiu por algum tempo, até que decidi dar uma olhada mais de perto. Muitos deles dizem que para comparar strings você deve usar equals
e não ==
. Espero que nesta resposta eu seja capaz de dizer a diferença.
A melhor maneira de responder a essa pergunta é fazer algumas perguntas para si mesmo. então vamos começar:
Qual é o resultado do programa abaixo:
String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);
Se você diz,
false
true
Eu vou dizer que você está certo, mas por que você disse isso ? e Se você diz que a saída é,
true
false
Eu vou dizer que você está errado, mas ainda vou perguntar, por que você acha isso certo?
Ok, vamos tentar responder a este:
Qual é o resultado do programa abaixo:
String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);
Agora, se você diz,
false
true
Eu vou dizer que você está errado, mas por que está errado agora ? a saída correta para este programa é
true
false
Por favor, compare o programa acima e tente pensar sobre isso.
Está bem. Agora isso pode ajudar (leia isto: imprima o endereço do objeto - não é possível, mas ainda podemos usá-lo.)
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));
você pode apenas tentar pensar na saída das últimas três linhas no código acima: para mim, o ideone imprimiu isso ( você pode verificar o código aqui ):
false
true
true
false
mango mango
false
true
17225372
17225372
5433634
Oh! Agora você vê que identityHashCode (manga) é igual a identityHashCode (mango2), mas não é igual a identityHashCode (mango3)
Mesmo que todas as variáveis de string - manga, manga2 e manga3 - tenham o mesmo valor, que é "manga", identityHashCode()
ainda não são as mesmas para todos.
Agora tente descomentar esta linha // mango2 = "mang";
e executá-la novamente desta vez, para ver todas as três identityHashCode()
diferentes. Hmm, que é uma dica útil
sabemos que se hashcode(x)=N
e hashcode(y)=N
=>x is equal to y
Não tenho certeza de como o java funciona internamente, mas presumo que foi o que aconteceu quando eu disse:
mango = "mango";
java criou uma string "mango"
que foi apontada (referenciada) pela variável mango
algo como isto
mango ----> "mango"
Agora, na próxima linha, quando eu disse:
mango2 = "mango";
Na verdade, reutilizou a mesma string "mango"
que se parece com isso
mango ----> "mango" <---- mango2
Mango e mango2 apontando para a mesma referência Agora, quando eu disse
mango3 = new String("mango")
Na verdade, ele criou uma referência completamente nova (string) para "manga". que se parece com isso,
mango -----> "mango" <------ mango2
mango3 ------> "mango"
e é por isso que quando eu coloco os valores para mango == mango2
, ele coloca true
. e quando eu coloco o valor para mango3 == mango2
, ele coloca false
(mesmo quando os valores eram os mesmos).
e quando você descomentou a linha, // mango2 = "mang";
na verdade, ele criou uma string "mang" que virou nosso gráfico assim:
mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"
É por isso que o identityHashCode não é o mesmo para todos.
Espero que isso ajude vocês. Na verdade, eu queria gerar um caso de teste em que == falha e equals () passa. Por favor, sinta-se livre para comentar e me avise se eu estiver errado.
mango == mango2
acontece porque você não criou mango2
como um novo objeto String e apenas referenciou diretamente "mango"
?
O operador == testa se duas variáveis têm as mesmas referências (também conhecido como ponteiro para um endereço de memória) .
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)
Enquanto o método equals () testa se duas variáveis se referem a objetos que possuem o mesmo estado (valores) .
String foo = new String("abc");
String bar = new String("abc");
if(foo.equals(bar))
// True (The objects are identical but not same)
Felicidades :-)
Você precisará substituir a função equals (junto com outras) para usá-la com classes personalizadas.
O método equals compara os objetos.
O ==
operador binário compara os endereços de memória.
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
Lembre-se de que isso .equals(...)
deve ser implementado pela classe que você está tentando comparar. Caso contrário, não há muito sentido; a versão do método para a classe Object faz o mesmo que a operação de comparação: Object # equals .
A única vez em que você realmente deseja usar o operador de comparação para objetos é quando você está comparando Enums. Isso ocorre porque há apenas uma instância de um valor Enum por vez. Por exemplo, dado o enum
enum FooEnum {A, B, C}
Você nunca terá mais de uma instância de A
cada vez, e o mesmo para B
e C
. Isso significa que você pode realmente escrever um método como este:
public boolean compareFoos(FooEnum x, FooEnum y)
{
return (x == y);
}
E você não terá nenhum problema.
Quando você avalia o código, fica muito claro que (==) compara de acordo com o endereço da memória, enquanto igual (Objeto o) compara hashCode () das instâncias. É por isso que se diz que não quebre o contrato entre equals () e hashCode () se você não enfrentar surpresas mais tarde.
String s1 = new String("Ali");
String s2 = new String("Veli");
String s3 = new String("Ali");
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
System.out.println("(s1==s2):" + (s1 == s2));
System.out.println("(s1==s3):" + (s1 == s3));
System.out.println("s1.equals(s2):" + (s1.equals(s2)));
System.out.println("s1.equal(s3):" + (s1.equals(s3)));
/*Output
96670
3615852
96670
(s1==s2):false
(s1==s3):false
s1.equals(s2):false
s1.equal(s3):true
*/
Aqui está uma regra geral para a diferença entre relational operator ==
e the method .equals()
.
object1 == object2
compara se os objetos referenciados por objeto1 e objeto2 se referem ao mesmo local de memória no Heap .
object1.equals(object2)
compara os valores de objeto1 e objeto2, independentemente de onde eles estão localizados na memória .
Isso pode ser demonstrado bem usando String
Cenário 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
Cenário 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
Essa comparação de cadeias poderia ser usada como base para comparar outros tipos de objetos.
Por exemplo, se eu tiver uma classe Person , preciso definir a base de critérios com a qual compararei duas pessoas . Digamos que essa classe de pessoa tenha variáveis de instância de altura e peso.
Portanto, para criar objetos person person1 and person2
e comparar esses dois usando o .equals()
, preciso substituir o método equals da classe person para definir com base em quais variáveis de instância (altura ou peso) a comparação será.
No entanto, o == operator will still return results based on the memory location of the two objects(person1 and person2)
.
Para facilitar a generalização dessa comparação de objetos pessoais, criei a seguinte classe de teste. Experimentar esses conceitos revelará toneladas de fatos .
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;
}
}
O resultado desta execução de classe é:
is person1 == person2 ? false
is person2 == person3 ? true
is person2.equals(person3) ? true
is person2.equals(person4) ? true
is person2.equals(person4) ? false
== operador sempre a referência é comparada. Mas no caso de
método equals ()
depende da implementação se formos substituídos pelo método equals do que comparar o objeto com base na implementação dada no método substituído.
class A
{
int id;
String str;
public A(int id,String str)
{
this.id=id;
this.str=str;
}
public static void main(String arg[])
{
A obj=new A(101,"sam");
A obj1=new A(101,"sam");
obj.equals(obj1)//fasle
obj==obj1 // fasle
}
}
no código acima, obj e obj1 contêm os mesmos dados, mas a referência não é a mesma; portanto, igual a return false e == also. mas se substituímos o método é igual a
class A
{
int id;
String str;
public A(int id,String str)
{
this.id=id;
this.str=str;
}
public boolean equals(Object obj)
{
A a1=(A)obj;
return this.id==a1.id;
}
public static void main(String arg[])
{
A obj=new A(101,"sam");
A obj1=new A(101,"sam");
obj.equals(obj1)//true
obj==obj1 // fasle
}
}
sabe check-out ele retornará verdadeiro e falso para o mesmo caso, apenas nós substituímos
método dos iguais.
compara objeto no básico do conteúdo (id) do objeto
mas ==
ainda compara referências de objeto.
A principal diferença entre == e igual a () é
1) == é usado para comparar primitivas.
Por exemplo :
String string1 = "Ravi";
String string2 = "Ravi";
String string3 = new String("Ravi");
String string4 = new String("Prakash");
System.out.println(string1 == string2); // true because same reference in string pool
System.out.println(string1 == string3); // false
2) equals () é usado para comparar objetos. Por exemplo :
System.out.println(string1.equals(string2)); // true equals() comparison of values in the objects
System.out.println(string1.equals(string3)); // true
System.out.println(string1.equals(string4)); // false
==
pode ser usado em muitos tipos de objetos, mas você pode usar Object.equals
para qualquer tipo, especialmente Strings e Google Map Markers.
public class StringPool {
public static void main(String[] args) {
String s1 = "Cat";// will create reference in string pool of heap memory
String s2 = "Cat";
String s3 = new String("Cat");//will create a object in heap memory
// Using == will give us true because same reference in string pool
if (s1 == s2) {
System.out.println("true");
} else {
System.out.println("false");
}
// Using == with reference and Object will give us False
if (s1 == s3) {
System.out.println("true");
} else {
System.out.println("false");
}
// Using .equals method which refers to value
if (s1.equals(s3)) {
System.out.println("true");
} else {
System.out.println("False");
}
}
}
---- Saída ----- verdadeiro falso verdadeiro
Vale a pena acrescentar que, para objetos wrapper para tipos primitivos - por exemplo, Int, Long, Double - == retornará true se os dois valores forem iguais.
Long a = 10L;
Long b = 10L;
if (a == b) {
System.out.println("Wrapped primitives behave like values");
}
Por outro lado, colocando os dois Longs acima em dois ArrayLists separados, iguais os vê como iguais, mas == não.
ArrayList<Long> c = new ArrayList<>();
ArrayList<Long> d = new ArrayList<>();
c.add(a);
d.add(b);
if (c == d) System.out.println("No way!");
if (c.equals(d)) System.out.println("Yes, this is true.");
Long a = 128l; Long b = 128l; System.out.println(a == b);
O pool de String (também conhecido como interno ) e o pool de números inteiros diminuem ainda mais a diferença e podem permitir que você use ==
objetos em alguns casos, em vez de.equals
Isso pode lhe proporcionar melhor desempenho (?), Ao custo de maior complexidade.
Por exemplo:
assert "ab" == "a" + "b";
Integer i = 1;
Integer j = i;
assert i == j;
Troca de complexidade: o seguinte pode surpreendê-lo:
assert new String("a") != new String("a");
Integer i = 128;
Integer j = 128;
assert i != j;
Aconselho que você fique longe dessa micro-otimização e sempre use .equals
para objetos e ==
para primitivas:
assert (new String("a")).equals(new String("a"));
Integer i = 128;
Integer j = 128;
assert i.equals(j);
Em suma, a resposta é "Sim".
Em Java, o ==
operador compara os dois objetos para ver se eles apontam para o mesmo local de memória; enquanto o .equals()
método realmente compara os dois objetos para ver se eles têm o mesmo valor.
Basicamente, ==
compara se dois objetos têm a mesma referência na pilha, portanto, a menos que duas referências estejam vinculadas ao mesmo objeto, essa comparação será falsa.
equals()
é um método herdado da Object
classe Esse método, por padrão, compara se dois objetos têm a mesma referência. Isso significa:
object1.equals(object2)
<=> object1 == object2
No entanto, se você deseja estabelecer a igualdade entre dois objetos da mesma classe, substitua esse método. Também é muito importante substituir o método hashCode()
se você tiver substituído equals()
.
Implementar hashCode()
ao estabelecer a igualdade faz parte do Java Object Contract. Se você estiver trabalhando com coleções e não tiver implementado hashCode()
, Strange Bad Things pode acontecer:
HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));
null
será impresso após a execução do código anterior, se você não tiver implementado hashCode()
.
Como o Java não suporta sobrecarga do operador, == se comporta de maneira idêntica para todos os objetos, mas equals () é o método, que pode ser substituído em Java e a lógica para comparar objetos pode ser alterada com base nas regras de negócios.
A principal diferença entre == e igual em Java é que "==" é usado para comparar primitivas, enquanto o método equals () é recomendado para verificar a igualdade de objetos.
A comparação de cadeias é um cenário comum de uso dos métodos == e igual. Como a classe java.lang.String substitui o método equals, ele retornará true se dois objetos String contiverem o mesmo conteúdo, mas == só retornará true se duas referências estiverem apontando para o mesmo objeto.
Aqui está um exemplo de comparação de duas Strings em Java para igualdade usando o método == e equals (), que esclarecerá algumas dúvidas:
public class TEstT{
public static void main(String[] args) {
String text1 = new String("apple");
String text2 = new String("apple");
//since two strings are different object result should be false
boolean result = text1 == text2;
System.out.println("Comparing two strings with == operator: " + result);
//since strings contains same content , equals() should return true
result = text1.equals(text2);
System.out.println("Comparing two Strings with same content using equals method: " + result);
text2 = text1;
//since both text2 and text1d reference variable are pointing to same object
//"==" should return true
result = (text1 == text2);
System.out.println("Comparing two reference pointing to same String with == operator: " + result);
}
}