Digamos que eu crie um objeto e o adicione ao meu ArrayList
. Se eu criar outro objeto com exatamente a mesma entrada do construtor, o contains()
método avaliará os dois objetos como sendo os mesmos? Suponha que o construtor não faça nada de engraçado com a entrada e as variáveis armazenadas nos dois objetos são idênticas.
ArrayList<Thing> basket = new ArrayList<Thing>();
Thing thing = new Thing(100);
basket.add(thing);
Thing another = new Thing(100);
basket.contains(another); // true or false?
class Thing {
public int value;
public Thing (int x) {
value = x;
}
equals (Thing x) {
if (x.value == value) return true;
return false;
}
}
É assim que o class
deve ser implementado para ter contains()
retorno true
?
java
object
arraylist
evaluation
Mantas Vidutis
fonte
fonte
Object
e não umThing
. Caso contrário, seu método equals não será usado. :)Collections
faça suas coisas de maneira otimizada, o que significa quecontains()
primeiro verifica oshashCode
s dos dois objetos e só então chamaequals()
. Se oshashCode
forem diferentes (o que sempre ocorre em duas instâncias diferentes deThing
), oequals()
método não será chamado. Como regra geral, quando você substituiequals()
, não se esqueça de substituí-lohashCode()
também.Eu acho que as implementações certas devem ser
fonte
if
declaração é desnecessária.instanceof
basta.object != null
condição é desnecessária, porque tambémobject instanceof Thing
verifica se o objeto não é nulo.O ArrayList usa o método equals implementado na classe (a classe Thing do seu caso) para fazer a comparação igual.
fonte
Geralmente, você também deve substituir
hashCode()
sempre que substituirequals()
, mesmo que seja apenas pelo aumento de desempenho.HashCode()
decide em qual 'bloco' o seu objeto é classificado ao fazer uma comparação; portanto, quaisquer dois objetosequal()
avaliados como true devem retornar o mesmohashCode
value()
. Não me lembro do comportamento padrão dehashCode()
(se retornar 0, seu código deverá funcionar lentamente, mas se retornar o endereço, seu código falhará). Lembro-me de várias vezes em que meu código falhou porque esqueci de substituirhashCode()
. :)fonte
Ele usa o método equals nos objetos. Portanto, a menos que Thing substitua igual e use as variáveis armazenadas nos objetos para comparação, ele não retornará true no
contains()
método.fonte
Você deve escrever:
Agora funciona;)
fonte
Só queria observar que a seguinte implementação está errada quando
value
não é um tipo primitivo:Nesse caso, proponho o seguinte:
fonte
Outros pôsteres abordaram a questão sobre como o contains () funciona.
Um aspecto igualmente importante da sua pergunta é como implementar corretamente equals (). E a resposta para isso é realmente dependente do que constitui a igualdade de objetos para essa classe específica. No exemplo que você forneceu, se você tiver dois objetos diferentes, ambos com x = 5, eles são iguais? Realmente depende do que você está tentando fazer.
Se você está interessado apenas na igualdade de objetos, a implementação padrão de .equals () (a fornecida por Object) usa apenas identidade (ou seja, este == outro). Se é isso que você deseja, simplesmente não implemente equals () em sua classe (deixe herdar de Object). O código que você escreveu, embora meio que correto, se você estiver procurando por identidade, nunca apareceria em uma classe real b / c, pois não oferece nenhum benefício sobre o uso da implementação padrão Object.equals ().
Se você está apenas começando com esse material, recomendo fortemente o livro Java Efetivo de Joshua Bloch. É uma ótima leitura e abrange esse tipo de coisa (além de como implementar corretamente equals () quando você está tentando fazer mais do que comparações baseadas em identidade)
fonte
Atalho do JavaDoc :
booleano contém (Objeto o)
Retorna true se esta lista contiver o elemento especificado. Mais formalmente, retorna true se e somente se esta lista contiver pelo menos um elemento e tal que (o == null? E == null: o.equals (e))
fonte