Comparar objetos

24 respostas
guilhermetonetto

Boa tarde,

Tenho dois objetos do tipo Cliente e preciso comparar os atributos de cada um se mudo algo. Tipo

clienteNew.getNome().equals(clienteOld.getNome())

mas esta entidade possui 60 atributos tem um jeito mais fácil de fazer do que fazer um for e fazer if para cada atributo para ver qual mudo.

Espero ter sido o mais claro possivel :slight_smile:

[]'s

24 Respostas

criador

Então você tem um array de clientes (Cliente[]) ?

Abraço!

tinorberto

um objeto com 60 atributos??? ou são 60 objetos em um array?

marcosharbs

procure por reflection

E

guilhermetonetto:
Boa tarde,

Tenho dois objetos do tipo Cliente e preciso comparar os atributos de cada um se mudo algo. Tipo

clienteNew.getNome().equals(clienteOld.getNome())

mas esta entidade possui 60 atributos tem um jeito mais fácil de fazer do que fazer um for e fazer if para cada atributo para ver qual mudo.

Espero ter sido o mais claro possivel :slight_smile:

[]'s

http://commons.apache.org/beanutils/

guilhermetonetto

nao é um array de objetos e sim dois objetos Cliente e eu quero comparar os atributos se é diferente ou não

pmlm

Implementa o equals. O Eclipse faz isso automaticamente.

criador

Poste seu código para melhor visualização do seu problema.

Abraço!

guilhermetonetto

o Eclipse faz automaticamente o código de comparação de dois objetos ?

kenneth

Fala cara…

Eu concordo com o marcosharbs

Se vc quer fazer uma coisa mais dinamica, pode usar reflection…
Vc pode ler os metodos da classe e invoca-los em tempo de execucao…

Da uma olhada:
http://www.guj.com.br/article.show.logic?id=10

Abraco!

pmlm

No eclipse, na classe Cliente, botão direito :arrow: Source :arrow: Generate hashCode() and equals()

Depois, onde queres comparar é so fazer

if(clienteNew.equals(clienteOld))
renamed

pmlm:
No eclipse, na classe Cliente, botão direito :arrow: Source :arrow: Generate hashCode() and equals()

Depois, onde queres comparar é so fazer

if(clienteNew.equals(clienteOld))

mto BOA DICA!!!

guilhermetonetto

valeu ae pessoal!

Vou dar uma olhada em reflection e beanutils quando sobrar um tempo. Já implementei no modo tradicional com if e else if’s :slight_smile:

valeu pelas dicas

[]'s a todos

sergiotaborda

Equals não faz o que vc quer. Vc tem que utilizar reflection. Pegar todos os campos e comparar
algo assim :

public boolean  compare (Cliente a , Cliente b){
Field[] fields = Cliente.class.getFiedls();

for (Field f : fields ){
    if (! f.getValue(a).equals(f.getValue(b)){
      return false; // não são iguais
   }
}


return true; // são iguais.
}
pmlm

O equals faz exactamente o que ele quer, se for correctamente implementado na entidade.

Há duas formas de implementar o equals:

  • automaticamente pelo eclipse.O eclipse pergunta quais os campos que devem ser iguais para o equals dar true e implementa automaticamente todos os ifs

  • usando reflection, que poderá ser mais ou menos assim (não testei o código)

import org.apache.commons.lang.builder.EqualsBuilder;
(...)
  public boolean equals(Object other) {
        if (other == null) {
            return false;
        }
        if (!(other.getClass().isInstance(this))) {
            return false;
        }

        EqualsBuilder builder = null;
        for (Field f : this.getClass().getFields()) {
            builder.append(f.get(this), f.get(other));
        }


        if (builder == null) {
            return super.equals(other);
        }
        return builder.isEquals();
    }
marcosharbs

???

O equals(Object obj) não é nada a ver do eclipse é um método da classe Object, da qual todos os objetos decendem direta ou indiretamente,
e ele não implementa automaticamente todos os ifs, se vc olhar a implementação dele na classe Object é essa:

public boolean equals(Object obj) {
     return (this == obj);
}

se não me engano ele compara se os dois objetos estão referenciando o mesmo lugar de memória,
tanto que se por exemplo vc tiver uma classe Usuario e um atributo nome nessa classe
e criar duas instancias da classe Usuario e setar o mesmo nome pros dois e der um equals ele vai dar false
so se vc claro sobrescrever o metodo equals nessa classe pra retorna true se os dois nomes forem iguais

sergiotaborda

pmlm:
O equals faz exactamente o que ele quer, se for correctamente implementado na entidade.

Não. É exatamente isso que estou dizendo. Se ele implementar equals corretamente , equals não fará a comparação de todos os campos.

Nunca se implementa equals via reflection. Não porque é tecnicamente impossivel, mas porque é logicamente errado.

O método equals não compara todos os atributos do objeto. Isso é uma implementação errada de equals.

Equals diz se os objetos são equivalentes. O que o colega quer é saber se eles são exatamente iguais campo a campo, não apenas equivalentes.

guilhermetonetto

é tipo oq eu quero é que isso aconteça.

cliente.getNome().equals(clienteOld.getNome())

mas tem outro problema é que o equals quando tem

cliente.getCep().getNumeroCep().equals(clienteOld.getCep().getNumeroCep())

nesse código eu vejo o problema de que se o getCep() for nulo vai dar nullpointer e se eu comparar assim

cliente.getCep().equals(clienteOld.getCep())

sempre serão diferentes, pois até onde eu sei ele compara os endereços e não os valores.

marcosharbs
cliente.getCep().equals(clienteOld.getCep())

na verdade isso num vai ser diferente (se as Strings forem iguais) pois vc está comparando duas Strings, imagino que o atributo cpf deve ser uam String,
agora se fizer cliente.equals(clienteOld) vai retornar false pois devem ser duas instancias diferentes de objeto

guilhermetonetto

neste caso o getCep() seria um objeto dentro de cliente , claro q isso é um exemplo.

pmlm

marcosharbs:
???

O equals(Object obj) não é nada a ver do eclipse é um método da classe Object, da qual todos os objetos decendem direta ou indiretamente,
e ele não implementa automaticamente todos os ifs, se vc olhar a implementação dele na classe Object é essa:

Meus amigos, ninguém está falando do método equals tal como está implementado na classe Object, mas sim de uma implementação do equals feita por ele. Reescrever o método de uma classe pai, certamente sabem o que isso é, certo?

Se eu quero saber se dois objectos são iguais, tenho de reescrever a minha definição de igual. Mais correcto do que implementar um método comparar ou outra coisa qualquer é reescrever o equals para a entidade em causa.

O eclipse faz isso automaticamente com todos aqueles ifs e verificando se os campos estão a null para não dar NullPointerException. Pode também ser implementado com reflection mais ou menos como eu já pus atrás. Qualquer uma dessas formas funciona de certeza absoluta.

Implementação errada de equals? Porquê? O método equals é implementado da forma que eu quero para quando faço entidade1.equals(entidade2) devolva true quando pelas minhas regras forem iguais e devolva false quando forem diferentes.

sergiotaborda

Não. O método equals não é implementado da forma que vc quer. Ele é implementado segundo uma certa lógica.
Esta logica especifica que o método deve ter certas propriedades e que deve verificar se os objetos são equivalentes.

Objetos equivalentes não precisam ser iguais campo a campo. Claro que , objecto iguais campo a campo, são automáticamente equivalentes sob qq definição.

Comparar todos os atributos do método cegamente é errado para implementação de equals. Apenas os atributos relevantes devem ser comparados.

Se ainda não ficou claro, o que o colega quer é saber se o objeto foi modificado , por isso ele quer comparar todos os campos um a um, ele não quer saber se o objeto é equivalente, isso ele já sabe que é.
A situação é classica quando vc manda um objeto para edição e depois tem que descobrir se foi editado para saber se precisa mexer em outras coisas, nomalmente o banco.

Existem tecnicas melhores que a comparação campo a campo (proxy dinamico), mas a comparação campo a campo tb funciona e é menos intrusiva. É um simples loop que compara os campos… não é rocket cience… nem é a implementação de equals.

pmlm

Certo, concordo que o método equals não deve verificar todas as propriedades. Cabe a cada programador decidir, segundo as suas regras de negócio de quais são a propriedades necessárias.

O que ele precisa então será de implementar o compareTo, não?

sergiotaborda

pmlm:
Certo, concordo que o método equals não deve verificar todas as propriedades. Cabe a cada programador decidir, segundo as suas regras de negócio de quais são a propriedades necessárias.

O que ele precisa então será de implementar o compareTo, não?

Tb não. compareTo é para estabelecer ordem de maior e menor.

O método que ele precisa não é da classe. É um método utilitário que compara objetos quaisquer campo a campo.

public static <T> isModified ( T original, T edited){

 // true se edited é diferente em algum detalhes de original
}
marcosharbs
sergiotaborda:
pmlm:
Certo, concordo que o método equals não deve verificar todas as propriedades. Cabe a cada programador decidir, segundo as suas regras de negócio de quais são a propriedades necessárias.

O que ele precisa então será de implementar o compareTo, não?

Tb não. compareTo é para estabelecer ordem de maior e menor.

O método que ele precisa não é da classe. É um método utilitário que compara objetos quaisquer campo a campo.

public static <T> isModified ( T original, T edited){

 // true se edited é diferente em algum detalhes de original
}

concordo, compareTo não server nesse caso e sim para ordenar coleções

Criado 14 de outubro de 2009
Ultima resposta 19 de out. de 2009
Respostas 24
Participantes 9