Equals (geral de saco cheio hehe)

13 respostas
C

Eu sei que já foram abertos vários tópicos com o mesmo tema, porém não consegui (por incapacidade minha ou azar de pesquisar os tópicos errados) entender o método por completo.
De qualquer forma espero que me perdoem por criar mais um. :XD:

Foi dito por alguém que o equals compara conteúdos de objetos.
Pois bem:

MinhaClasse mc1 = new MinhaClasse();
MinhaClasse mc2 = new MinhaClasse();

System.out.println(mc1.equals(mc2));

Não deveria retornar true?
Ou a utilidade do equals só se restringe a strings?

13 Respostas

E

O equals só funciona se você sobrepô-lo (redefini-lo). Senão, é usada a implementação padrão, que simplesmente usa o “==” (ou seja, para o que você quer fazer, não funciona).

É igual à história do toString. Se você não redefinir o método toString, só imprime uma coisa enigmática em vez de imprimir o seu objeto direitinho.

Nada como usar linguagens trabalhosas como o Java - as coisas não vêm prontas e enlatadas como na linguagem Scala.

drsmachado

Sim, o método da classe Object analisa o conteúdo de dois objetos, comparando-os.
A questão, para o retorno ser true, é que, tudo o que se refere ao objeto A deve ser exatamente igual B e, quando chamamos o construtor, criamos um único objeto, independente de ter sido gerado a partir de uma classe única.
Portanto,

Classe a = new Classe();
Classe b = new Classe();
System.out.println(a.equals(b));

Retornará false e

Classe a = new Classe();
Classe b = a;
System.out.println(a.equals(b));

Deverá retornar true, pois o objeto instanciado é o mesmo.

ViniGodoy

Nada disso. O método equals da classe object não olha para nenhum conteúdo. O que ele olha é se os dois objetos apontam para o mesmo endereço de memória, e só.

Dois objetos podem ter absolutamente todos os campos idênticos e ainda assim, reprovarem no equals.

umendonca

Como o ViniGodoy disse, o equals compara as referências para os objetos na memória.
No caso do código abaixo ele vai comparar a referência de “a” com a referência de “b”. Como são objetos distintos, retornará FALSE…
Se você quer que o equals trabalhe segundo seus critérios você vai ter que sobrescrever o método na sua classe.

Classe a = new Classe();             // aponta para um ponto da memória
Classe b = new Classe();             // aponta para um outro ponto da memória
System.out.println(a.equals(b));     // retorna "false" pois as referências são diferentes

a = b;
System.out.println(a.equals(b));     // agora retorna "true" pois as duas referências apontam para o mesmo objeto

Espero ter ajudado.

Ulysses

gqferreira

Nada disso. O método equals da classe object não olha para nenhum conteúdo. O que ele olha é se os dois objetos apontam para o mesmo endereço de memória, e só.

Dois objetos podem ter absolutamente todos os campos idênticos e ainda assim, reprovarem no equals.

Mas se eu tiver duas String’s, suponhando String x e String y, as duas com o mesmo valor e eu fizer um equals enrte as duas, vai dar true mesmo sendo objetos diferentes…

Nao entendi agora?!

ViniGodoy

Estavamos falando do comportamento padrão do equals, que é o do == (note que ele fala no equals da classe Object).

O comportamento sobrescrito do equals na classe String compara conteúdo.

Ainda assim, é um erro assumir que o equals sempre irá comparar todos os campos. Em aplicações de banco de dados, por exemplo, é comum que o equals só compare ids. A definição de igualdade vai variar de acordo com quem sobrescrever o equals.

lugaid

Só complementando…
Outro perigo de usar o método equals() é se o objeto for nulo…
Se o equals() for utilizado em um método nulo, o programa não compila, dando java.lang.NullPointerException
Aí nesse caso, o melhor é utilizar o ==

pmlm

lugaid:
Só complementando…
Outro perigo de usar o método equals() é se o objeto for nulo…
Se o equals() for utilizado em um método nulo, o programa não compila, dando java.lang.NullPointerException
Aí nesse caso, o melhor é utilizar o ==

WTF? Se o objecto for null deve ser protegido dessa situação convenientemente.
Agora utilizar == em vez de equals não faz NENHUM sentido.

ViniGodoy

O objeto que o equals recebe pode ser nulo. Está no contrato do equals que ele deve retornar false nesses casos.
O objeto que chama equals não pode ser nulo. E isso não é válido só para o equals, mas para qualquer método.

douglaskd

li o tópico e surgiu algumas dúvidas

1° quando vamos comparar 2 objetos, sobrescrevemos o método Equals, por que não devemos/podemos criar um método com nome diferente?

exemplo:

public boolean Equals( Object o ) { if( (o instanceof Teste) && ((Teste)o).number == this.number ) return true; else return false; }

public boolean Igual( Object o ) { if( (o instanceof Teste) && ((Teste)o).number == this.number ) return true; else return false; }

2° dúvida, como eu poderia fazer para que o método getInstan funcionasse?

public boolean Equais( Object o ) { if( (o instanceof this.getInstan()) && ((this.getInstan)o).number == this.number ) return true; else return false; }

desde já agradeço

pmlm

Executa o seguinte código:

import java.util.ArrayList;
import java.util.List;

public class EqualsTest {

      public static void main(String[] args) {
        new EqualsTest().doIt();
    }

    public void doIt() {
        List<MyClass> list = new ArrayList<MyClass>();

        MyClass class1 = new MyClass();
        class1.setKey(1);
        class1.setAString("xpto");
        class1.setAnotherString("blabla");

        list.add(class1);

        MyClass class2 = new MyClass();
        class2.setKey(1);

        if (list.contains(class2)) {
            System.out.println("Chave já existe");
        } else {
            System.out.println("Chave não existe");
        }
    }

    class MyClass {

        int key;

        String aString;

        String anotherString;

        public MyClass() {

        }

        public int getKey() {
            return key;
        }

        public void setKey(int key) {
            this.key = key;
        }

        public String getAString() {
            return aString;
        }

        public void setAString(String string) {
            aString = string;
        }

        public String getAnotherString() {
            return anotherString;
        }

        public void setAnotherString(String anotherString) {
            this.anotherString = anotherString;
        }

        public boolean equals(Object other) {
            if (other == null) {
                return false;
            }
            if (!(other instanceof MyClass)) {
                return false;
            }
            MyClass otherC = (MyClass) other;
            return key == otherC.key;
        }

    }
}

E agora muda o nome do método equals para qualquer outra coisa e volta a executar. Mesmo não chamando o equals explicitamente no código, ele é usado pelo contains do List.
E quando se sobreescreve o equals deve também sobreescrever-se o hashCode para garantir que dois objectos iguais devolvem o mesmo hashCode.

ViniGodoy

Podemos criar métodos com outros nomes. Mas as classes do Java (como as da Collections Framework) vão procurar um método chamado equals. As collections usam equals em diversas situações, como no método contains e nos maps.

Note que equals é definido em object, portanto, é uma certeza para as classes do Java que o método equals existe, quando elas não podem afirmar nada sobre o seu método igual.

WellingtonRamos
lugaid:
Só complementando... Outro perigo de usar o método equals() é se o objeto for nulo... Se o equals() for utilizado em um método nulo, o programa não compila, dando java.lang.NullPointerException Aí nesse caso, o melhor é utilizar o ==
E desde quando NullPointerException não permite compilar?...

O objeto que possivelmente é nulo nunca será o objeto a utilizar o equals mas será parâmetro

Object nullObj = null;

Object notNullObj = new Object();

//faça isso:
notNullObj.equals(nullObj);

//não faça isso
nullObj.equals(notNullObj); //Isso vai dar NullPointerException
Criado 12 de novembro de 2010
Ultima resposta 16 de nov. de 2010
Respostas 13
Participantes 10