Pessoal dado o seguinte trecho de código do MASTER EXAM eu gostaria que você me ajudassem a entender essa questão…
class SortOf{
String name;
int bal;
String code;
short rate;
public int hashCode(){
return (code.lenght()*bal);
}
public boolean equals(Object o){
//insert code here
}
}
which of the following will fulfill the equals() and hashCode() contracts for thi class(Choose all tha apply).
A return ((SortOf)o).bal == this.bal;
B return ((SortOf)o).code.lenght() == this.code.lenght();
C return ((SortOf)o).code.lenght() * (iSortOf)o).bal == this.code.lenght() * this.bal;
D return ((SortOf)o).code.lenght() * (iSortOf)o).bal * ((SortOf)o).rate == this.code.lenght() * this.bal * this.rate;
Pessoal qual a resposta? Se alguem puder explicar eu agradeço !
Em poucas palavras, o contrato entre hashCode e equals diz que:
Se a.hashCode == b.hashCode, então talvez a == b;
Se a.equals(b) == true, então obrigatoriamente a.hashCode == b.hashCode;
Ou seja, se dois objetos são iguais, eles devem ter o mesmo hashCode, mas o fato de dois objetos terem o mesmo hashCode não quer dizer que sejam iguais. Pense em hashCode como os índices de uma lista telefônica: Marcelo e Márcio têm o hashCode "M", mas não são a mesma pessoa.
Uma dica é utilizar no cálculo do hashCode os mesmos atributos utilizados para determinar o [i]equals[/i].
Quanto à questão, eu marcaria [b]C[/b].
olha a D nao é valido para a questao pq o calculo nunca vai ser igual… a letra B so traz o tamanho, a letra A claramente que é errada entao a letra C. Outra questao é as variaveis que está em teste tem que ser as mesma que está tanto no equals quanto no hasCode… se vc está passando (code e bal); entao vc vai ter que testar no seu equals essas variaveis para obter true e true… A nao ser ser que seu hashCode fosse ineficiente tipo.
int hashCode(){
return 10;
}
para qualquer teste la no equals ele vai retornar 10.
O contrato de equals também diz que se o método deve retornar false se null for passado: “For any non-null reference value x, x.equals(null) should return false.” (Retirado da classe Object)
E todos esses casos lançam uma NullPointerException.
É por essas e outras que odeio essas questões de exame.
O hashCode leva em conta o tamanho do código e o valor da variável bal.
Se não fosse pela questão do nulo, o método equals correto deveria levar em consideração esses dois parâmetros também, ou teríamos a possibilidade de métodos iguais terem hashCodes diferentes.
Portanto, seria a letra C.
De qualquer forma, é uma questão mal formulada. Se a resposta não for nenhuma, trata-se de uma pegadinha. Se for a letra C, é porque esqueceram de um dos itens do contrato do equals.
Salvo pela questão do null que o Viny levantou eu ficaria com a alternativa A.
ball é o único elemento que faz sentido no proposto, os outros são, me parecem, irrelevante, vejam:
B) se o tamanho de dois códigos forem iguais, então SortOf será igual??? acho que podemos descartar.
C) return ((SortOf)o).code.lenght() * (iSortOf)o).bal == this.code.lenght() * this.bal;
Se em o vc tiver tamanho do código 2 e bola 3 e no segundo elemento da expressão de igualdade você tiver tamanho 3 e vola 2, então o objeto será considerado igual?
O item D sofre do mesmo problema que o item C, a presença do rate pode ser fundamental para o método equals, mas não ser obrigatorio para o hashCode…
[quote=Dieval Guizelini]Salvo pela questão do null que o Viny levantou eu ficaria com a alternativa A.
ball é o único elemento que faz sentido no proposto, os outros são, me parecem, irrelevante, vejam:
B) se o tamanho de dois códigos forem iguais, então SortOf será igual??? acho que podemos descartar.
C) return ((SortOf)o).code.lenght() * (iSortOf)o).bal == this.code.lenght() * this.bal;
Se em o vc tiver tamanho do código 2 e bola 3 e no segundo elemento da expressão de igualdade você tiver tamanho 3 e vola 2, então o objeto será considerado igual?
O item D sofre do mesmo problema que o item C, a presença do rate pode ser fundamental para o método equals, mas não ser obrigatorio para o hashCode…
É uma péssima questão na minha opnião.
fw[/quote]
B - codigo hashing iguais porem objetos false forma ineficiente
A - codigo hashin igual independete do equals…
C - testo os mesmo valores do hashcode buscando a forma eficiente…
D - forma ineficiente
Bom o masterExam tem muitos erros, essa questao pode ta errada… por isso que nao faço ele… deixa o cara muito confuso… ja encontrei erros absurdos la… e que na resposta dizia a letra que marquei… porem qdo fazia o exame… la tava outra letra… e outras perguntas mal formuladas… o exame nao é assim… lá… o codigo vai ta com as informações q v precisa pra aquela questao…
concordo com vocês quanto a qualidade da questão, mas a resposta correta é a C mesmo, o problema não está no contrato de equals, mas no contrato de hashCode.
Vejamos, para equals nós temos:
[quote]The equals method implements an equivalence relation on non-null object references:
It is reflexive: for any non-null reference value x, x.equals(x) should return true.
It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
For any non-null reference value x, x.equals(null) should return false. [/quote]
ref: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#equals(java.lang.Object)
e em hashCode, temos:
[quote]The general contract of hashCode is:
Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application. If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables. [/quote]
Logo, para que dois objetos iguais produzam o mesmo hashCode, teremos apenas a opção C, uma vez que em D existe uma terceira variável não considerada no método hash Apresentado.
Acho que no D a alternativa está certa. No início pensei o mesmo que você, mas daí olhando melhor percebi que embora haja uma variável a mais no equals, sempre que dois objetos foram iguais terão o mesmo hashcode.
O fato é que não será um bom hashcode, pois se repetirá sempre que os dois parâmetros iniciais forem os mesmos. Mas não é sobre a qualidade do hashcode que a questão fala de qualquer jeito.
O que não pode é ocorrer o contrário: o hashcode processar uma variável a mais do que o equals.
[ERRATA]
Falei besteira. O equals faz a igualdade com uma multiplicação. Então, pode haver dois objetos iguais com hashcodes diferentes.
Exemplo: um objeto com CodeLen=1 bal=1 rate=2 é igual a um objeto com CodeLen=1 bal=2 e rate=1, mas ambos tem hashs diferentes.
O que eu disse ali em cima só é valido para uma implementação padrão do equals, onde os campos são comparados item a item. Novamente, essa questão é um bom exemplo de como a coisa não deve ser feita.
Acho que no D a alternativa está certa. No início pensei o mesmo que você, mas daí olhando melhor percebi que embora haja uma variável a mais no equals, sempre que dois objetos foram iguais terão o mesmo hashcode.
O fato é que não será um bom hashcode, pois se repetirá sempre que os dois parâmetros iniciais forem os mesmos. Mas não é sobre a qualidade do hashcode que a questão fala de qualquer jeito.
O que não pode é ocorrer o contrário: o hashcode processar uma variável a mais do que o equals.[/quote]
Agora que eu notei, ele não está comparando campo a campo, e sim fazendo uma multiplicação.
De qualquer forma, é uma péssima implementação de equals do mesmo jeito.