Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

.equals não compara objetos corretamente

Criei uma classe StringTeste e não entendi o porquê do .equals não comparar corretamente os objetos Funcionario. Quando comparo duas Strings iguais, o retorno do .equals é True, porém quando compara dois objetos Funcionario iguais, o retorno sempre é False. Alguém saberia explicar porque isso acontece?

class StringTeste {

    public static void main(String[] args) {

        System.out.println("Objeto String:");

        String a = new String("Teste");
        String b = new String("Teste");

        if (a == b)
            System.out.println("a == b: True");
        else
            System.out.println("a == b: False");

        if (a.equals(b))
            System.out.println("a.equals(b): True");
        else
            System.out.println("a.equals(b): False");

        System.out.println("--------------------------------------");
        System.out.println("Objeto Funcionario:");

        Funcionario c = new Funcionario("José");
        Funcionario d = new Funcionario("José");

        if (c == d)
            System.out.println("c == d: True");
        else
            System.out.println("c == d: False");

        if (c.equals(d))
            System.out.println("c.equals(d): True");
        else
            System.out.println("c.equals(d): False");

    }
}

class Funcionario {
    String nome;

    Funcionario(String nome) {
        this.nome = nome;
    }
}
4 respostas
solução!

Fala, Luiz! Blz?

O operador == compara as referências das variáveis e não os conteúdos. Quando você cria duas variáveis, elas são alocadas em posições diferentes da memória. Por isso, você está recebendo uma mensagem informando que a == b retorna false.

Quando você usa o equals, esse método compara o conteúdo das variáveis (o texto delas, no caso de String). Aí, como os textos são iguais "Teste", o retorno do equals é true.

Pra que o teste do funcionário retorne True, você deve "ensinar" o objeto como fazer essa comparação. Isso se faz sobrescrevendo o método equals.

Peguei sua classe e sobrescrevi o método equais de Funcionario. Agora ele "sabe" como comparar para saber se é igual ou não a outro objeto funcionario. Veja que a comparação se dá apenas pelo nome, ou seja, se os nomes forem iguais, os objetos serão considerados iguais. Você pode colocar outras restrições como: só é igual se o nome, salário, departamento forem todos iguais, etc.

Acrescentei também um getNome().

class StringTeste {
    public static void main(String[] args) {

        System.out.println("Objeto String:");
        String a = new String("Teste");
        String b = new String("Teste");

        if (a == b)
            System.out.println("a == b: True");
        else
            System.out.println("a == b: False");

        if (a.equals(b))
            System.out.println("a.equals(b): True");
        else
            System.out.println("a.equals(b): False");

        System.out.println("--------------------------------------");
        System.out.println("Objeto Funcionario:");

        Funcionario c = new Funcionario("José");
        Funcionario d = new Funcionario("José");

        if (c == d)
            System.out.println("c == d: True");
        else
            System.out.println("c == d: False");

        if (c.equals(d))
            System.out.println("c.equals(d): True");
        else
            System.out.println("c.equals(d): False");
    }
}

class Funcionario {

    String nome;

    Funcionario(String nome) {
        this.nome = nome;
    }
    public String getNome() {
        return this.nome;
    }

    public boolean equals(Object obj) {
        Funcionario func = (Funcionario) obj;
        if (this.nome == func.getNome()) {
            return true;
        } else {
            return false;
        }
    }
}

Espero que te ajude a entender. Qualquer dúvida, só postar!

Abraço.

E ai Luiz Marcelo, não sei como esta a implementação da sua classe Funcionário, mas outra forma para você não ter que sobrescrever o método .equals é usar o seu atributo "nome". Como:

    if (c.nome.equals(d.nome))
            System.out.println("c.equals(d): True");
        else
            System.out.println("c.equals(d): False");

Matheus,

O problema é que pra cada nova propriedade criada dentro da classe, eu precisaria alterar todos os pontos que acessam o objeto para incluir mais uma comparação.

A solução do Manoel é mais adequada, pois sobrescreve o método equals(), sendo que a cada propriedade incluída na classe, eu precisaria apenas incluir a comparação no método interno da classe, e a alteração refletiria em todos os locais que o objeto está instanciado.

Realmente faz muito mais sentido, Luiz, mas eu pensei em por ser um código pequeno que poderia ser mais comodo. Mas sobrescrever o método é uma melhor pratica :D