Sobrepor o método equals, altera o contains?

Ea galera estou com uma dúvida e gostaria muito de entender, estou implementando um @override no método equals, para que não permita o registro de nomes idênticos, no sistema, e estou adicionando os objetos da minha classe em um ArrayList. Então quando tento fazer a comparação desses objetos dentro da lista, ele não traz a resposta esperada com o equals, mas quando passo no método contains, ele consegue compara com exito, queria saber se a sobrescrita no método equals tamém pode influenciar no contains, porque pelo que parece está acontecendo isso. Desde já agradeço.

public class Main {

    public static void main(String[] args) {
        Funcionarios func;
        ArrayList<Funcionarios> listFunc = new ArrayList();
        char opcao = 0, categoria = 0;
        int contador = 0;

        do {
            categoria = Leitor.lerCaracter("Para cadastrar professores digite: -P, para diretores -D");
            contador += +1;
            func = Visao.createFunc(contador, categoria);
            //System.out.println("********Iniciando Estrutura de condição**************");
            if (listFunc.contains(func)) {
                //System.out.println("********IF(1)**************");
                System.out.println("Usuário já registrado!");
            } else {
                //System.out.println("********else**************");
                listFunc.add(func);
            }

            opcao = Leitor.lerCaracter("Deseja continuar: se sim -s, se não -n");
        } while (opcao == 's');

        Visao.print(listFunc);
    }
}



public class Funcionarios {

    private int matricula;
    private String nome;
    private String cpf;
    private double salario;

    public Funcionarios(String nome, String cpf, double salario) {
        this.nome = nome;
        this.cpf = cpf;
        this.salario = salario;
    }

    public Funcionarios() {

    }

    @Override
    public boolean equals(Object obj) {

        Funcionarios temp = (Funcionarios) obj;
        
        if(getNome().equalsIgnoreCase(temp.getNome())) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        return "matricula= " + matricula + "\tnome= " + nome + "\tcpf= " + cpf + "\tsalario= " + salario;
    }

    public double getImpostoRenda() {
        return 0;
    }

    public int getMatricula() {
        return matricula;
    }

    public void setMatricula(int matricula) {
        this.matricula = matricula;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getCpf() {
        return cpf;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    public double getSalario() {
        return salario;
    }

    public void setSalario(double salario) {
        this.salario = salario;
    }

}

Não entendi essa parte. O que você quer dizer com fazer a comparação dentro da lista?

O contains usa o equals internamente, então o comportamento dele depende do equals. Veja um exemplo: https://ideone.com/3owlfR .

Também é recomendado que, se você sobrescreve o método equals, também sobrescreva o método hashcode, que é usado por outros métodos das coleções (Collections). A ideia é que, se 2 objetos são iguais (equals), eles tenham o mesmo hashcode. Não fazer isso pode levar a comportamentos estranhos.

Abraço.

Bom essa parte da comparação com equals, é que em vez de está usando o equals para comparar o objeto que está na minha lista, estou usando o contains, ele ta agindo da mesma forma que o equals, sabe me dizer porque isso ocorre?

Nessa linha que faço a comparação
if (listFunc.contains(func)) {
em vez de equals estou usando o contains, porque o equals não é reconhecido.

Você olhou o exemplo do link que eu coloquei?

Explica melhor o que você quer dizer com “o equals não é reconhecido”, possivelmente com o código que você estava tentando. Pois, para verificar se um elemento existe dentro de uma lista, você precisa usar contains. E se quer comparar o objeto de uma forma diferente do padrão, precisa sobrescrever o equals.

Abraço.

Eu ohei o exemplo. Conseguir entender, eu achava que a comparação tinha que acontece com equals e não com o contains, afinal eu estou sobrescrevendo o equals, mas pelo que você me explicou para verificar um elemento dentro de uma lista eu preciso fazer isso com o contains.

Obrigado pela explicação, me ajudou muito!

O contains utiliza o equals para comparar o conteúdo da lista, de uma lida na documentação.

Outra coisa, o método equals serve para comparar se dois objetos do mesmo tipo de dado são iguais entre si.

Você implementou o equals comparando somente o atributo nome, isso não faz sentido, pois se você tiver dois objetos Funcionarios com cpf, matricula e salario diferentes, mas nome igual, sua comparação vai retornar true e não deveria.

Dica: o nome da classe deveria ser Funcionario, no singular, pois cada instância dela representa um funcionário.

1 curtida

Pois é a resolução do problema que estava resolvendo, pedia que fosse sobrescrito o equals para que o usuário não informasse nomes iguais, mas eu penso que a melhor forma seria pela matricula ou cpf. Valeu pela informação da classe, mudei o nome dela para funcionario, e as subclasses também passei para o singular.

Obrigado!

1 curtida

Entendi. Infelizmente isso é coisa de professor que só tem experiência no mundo acadêmico e não conhece Java a fundo.

Para essa situação você poderia utilizar uma coleção do tipo TreeSet com um Comparator para o atributo nome.

Vou deixar uns links que explicam sobre a implementação dos métodos equals e hashcode:

@staroski, @TerraSkilll obrigado pela ajuda !

2 curtidas