Estou tentando substituir o método equals em Java. Eu tenho uma classe People
que tem basicamente 2 campos de dados name
e age
. Agora eu quero substituir o equals
método para que eu possa verificar entre 2 objetos Pessoas.
Meu código é o seguinte
public boolean equals(People other){
boolean result;
if((other == null) || (getClass() != other.getClass())){
result = false;
} // end if
else{
People otherPeople = (People)other;
result = name.equals(other.name) && age.equals(other.age);
} // end else
return result;
} // end equals
Mas quando escrevo age.equals(other.age)
, me dá um erro, pois o método de igualdade só pode comparar String e idade é Inteiro.
Solução
Usei ==
operador conforme sugerido e meu problema está resolvido.
java
overriding
equals
Castor
fonte
fonte
Respostas:
Resultado:
fonte
hash = 53 * hash
por isso que você está usando isso?getClass()
causará problemas se a classe tiver uma subclasse e for comparada com um objeto da superclasse.hashCode()
instanceof
operador ouisAssignableFrom
. Isso exigirá correspondência exata de tipo, em vez de correspondência de subtipo. - Requisito simétrico. Também para compararString
ou outros tipos de objetos, você pode usarObjects.equals(this.name,other.name)
.A introdução de uma nova assinatura de método que altera os tipos de parâmetro é chamada de sobrecarga :
Aqui
People
é diferente deObject
.Quando a assinatura de um método permanece idêntica à de sua superclasse, ela é chamada de substituição e a
@Override
anotação ajuda a distinguir as duas em tempo de compilação:Sem ver a declaração real de
age
, é difícil dizer por que o erro aparece.fonte
Não tenho certeza dos detalhes, pois você não postou o código inteiro, mas:
hashCode()
tambémequals
método deveria terObject
, nãoPeople
como seu tipo de argumento. No momento você está sobrecarregando, não substituindo, o método equals, que provavelmente não é o que você deseja, especialmente considerando que você verificará seu tipo posteriormente.instanceof
para verificar se é um objeto Pessoas, por exemploif (!(other instanceof People)) { result = false;}
equals
é usado para todos os objetos, mas não primitivos. Acho que você quer dizer que idade é umint
(primitivo), caso em que apenas use==
. Observe que um inteiro (com 'I' maiúsculo) é um objeto que deve ser comparado com iguais.Consulte Quais problemas devem ser considerados ao substituir equals e hashCode em Java? para mais detalhes.
fonte
fonte
Item 10: Obedeça o contrato geral ao substituir iguais
Cada instância da classe é inerentemente única . Isso é verdadeiro para classes como Thread, que representam entidades ativas em vez de valores. A implementação equals fornecida por Object tem exatamente o comportamento correto para essas classes.
Não há necessidade de a classe fornecer um teste de “igualdade lógica”. Por exemplo, java.util.regex.Pattern poderia ter substituído equals para verificar se duas instâncias de Pattern representavam exatamente a mesma expressão regular, mas os designers não pensaram que os clientes precisariam ou desejariam essa funcionalidade. Nessas circunstâncias, a implementação igual herdada de Object é ideal.
Uma superclasse já substituiu equals e o comportamento da superclasse é apropriado para esta classe. Por exemplo, a maioria das implementações de Set herdam suas implementações iguais de AbstractSet, implementações de List de AbstractList e implementações de Map de AbstractMap.
A classe é privada ou privada do pacote e você tem certeza de que seu método equals nunca será chamado. Se você for extremamente avesso a riscos, poderá substituir o método equals para garantir que ele não seja invocado acidentalmente:
O
equals
método implementa uma relação de equivalência. Possui estas propriedades:Reflexivo: para qualquer valor de referência não nulo
x
,x.equals(x)
deve retornar verdadeiro.Simétrico: para quaisquer valores de referência não nulos
x
ey
,x.equals(y)
deve retornar verdadeiro se e somente se y.equals (x) retornar verdadeiro.Transitivo: Para todos os valores de referência não nulos
x
,y
,z
, sex.equals(y)
os retornostrue
ey.equals(z)
retornostrue
, em seguida,x.equals(z)
deve retornartrue
.Consistente: Para quaisquer valores de referência não nulos
x
ey
, várias invocações dex.equals(y)
devem retornartrue
ou retornar consistentementefalse
, desde que nenhuma informação usada nas comparações de igual seja modificada.Para qualquer valor de referência não nulo
x
,x.equals(null)
deve retornarfalse
.Aqui está uma receita para um método de igualdade de alta qualidade:
Use o
==
operador para verificar se o argumento é uma referência a este objeto. Se sim, retorne verdadeiro. Esta é apenas uma otimização de desempenho, mas vale a pena se a comparação for potencialmente cara.Use o
instanceof
operador para verificar se o argumento tem o tipo correto. Caso contrário, retorna falso. Normalmente, o tipo correto é a classe em que o método ocorre. Ocasionalmente, é alguma interface implementada por esta classe. Use uma interface se a classe implementar uma interface que refina o contrato de igual para permitir comparações entre as classes que implementam a interface. Interfaces de coleção como Set, List, Map e Map.Entry têm esta propriedade.Converta o argumento para o tipo correto. Como essa conversão foi precedida por um teste de instância, é garantido o sucesso.
Para cada campo “significativo” na classe, verifique se aquele campo do argumento corresponde ao campo correspondente deste objeto. Se todos esses testes forem bem-sucedidos, retorna verdadeiro; caso contrário, retorna falso. Se o tipo na Etapa 2 for uma interface, você deve acessar os campos do argumento por meio de métodos de interface; se o tipo for uma classe, você poderá acessar os campos diretamente, dependendo de sua acessibilidade.
Para campos primitivos cujo tipo não é
float
oudouble
, use o==
operador para comparações; para campos de referência de objeto, chame oequals
método recursivamente; parafloat
campos, use oFloat.compare(float, float)
método estático ; e paradouble
campos, useDouble.compare(double, double)
. O tratamento especial de flutuador e campos duplos é necessária devido à existência deFloat.NaN
,-0.0f
e os valores duplos análogos; Embora você possa comparar os camposfloat
edouble
com os métodos estáticosFloat.equals
eDouble.equals
, isso implicaria no autoboxing em todas as comparações, o que teria um desempenho ruim. Paraarray
campos, aplique essas diretrizes a cada elemento. Se cada elemento em um campo de matriz for significativo, use um dosArrays.equals
métodos.Alguns campos de referência de objeto podem conter legitimamente
null
. Para evitar a possibilidade de aNullPointerException
, verifique a igualdade desses campos usando o método estáticoObjects.equals(Object, Object)
.fonte
hashCode()
. Também nota, que desde Java7 escritaequals()
ehashCode()
métodos tornou-se muito mais fácil usandoObjects.equals()
,Arrays.equals()
eObjects.hashCode()
,Arrays.hashCode()
.if (getClass() != obj.getClass()) ...
vez de usar o operador instanceof. Isso exigirá correspondência exata de tipo, em vez de correspondência de subtipo. - Requisito simétrico.Já que estou supondo que
age
seja do tipoint
:fonte
NullPointerException
ifname
énull
.name
nunca recebe umnull
valor atribuído ...Ao comparar objetos em Java, você faz uma verificação semântica , comparando o tipo e identificando o estado dos objetos para:
null
Regras:
a.equals(b) == b.equals(a)
equals()
sempre cedetrue
oufalse
, mas nunca umNullpointerException
,ClassCastException
ou qualquer outro lançávelComparação:
instanceof
para comparação de tipo (o que só funciona enquanto não houver subclasses e viola a regra de simetria quandoA extends B -> a instanceof b != b instanceof a)
.Para sua
Person
aula:Classe de utilitário genérico reutilizável:
Para sua
Person
classe, usando esta classe de utilitário:fonte
se idade for int, você deve usar == se for um objeto Integer, então você pode usar equals (). Você também precisa implementar o método hashcode se substituir equals. Detalhes do contrato estão disponíveis no javadoc da Object e também em várias páginas na web.
fonte
Aqui está a solução que usei recentemente:
fonte