import java.util.HashSet;
public class WrappedString
{
private String s;
public WrappedString(String s){ this.s = s;}
public static void main(String args[]){
HashSet<Object> hs = new HashSet<Object>();
WrappedString ws1 = new WrappedString("aardvark");
WrappedString ws2 = new WrappedString("aardvark");
String s1 = new String("aardvark");
String s2 = new String("aardvark");
System.out.println(hs.add(ws1));
System.out.println(hs.add(ws2));
System.out.println(hs.add(s1));
System.out.println(hs.add(s2));
System.out.println( hs.size() );
}
}
A) 0
B) 1
C) 2
D) 3
E) 4
F) Compilation fails
G) An exception is thrown at runtime
A resposta correta é a D. Porém, tenho uma dúvida. Acompanhem o raciocínio:
No primeiro hs.add ( hs.add(ws1) ), como não existe nenhum objeto dentro do conjunto ainda, ele é adicionado sem problema. No segundo hs.add ( hs.add(ws2) ) ele calcula primeiramente o hashcode. Será usado o hashcode da classe pertencente ao objeto que estou inserindo no HashMap, ou seja, será utilizado o hashcode da minha classe WrappedString. Porém, como eu não sobrescrevi o método hashcode, então o que será usado é o da implementação da classe Object. Na documentação da classe Object, está escrito:
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects.
Mas em primeiro lugar, eu não acho que essa informação é válida para 100% dos casos. Como hashcode retorna um int, temos que o número máximo de hashcodes permitidos são 2^32 = 4.294.967.296. Assim, imaginando um caso hipotético com 4.294.967.297 objetos do tipo WrappedString na memória (e considerando todos eles diferentes um do outro), temos que teremos pelo menos um hashcode repetido, mesmo sendo todos os objetos diferentes uns dos outros.
Voltando ao problema, considerando que o hashcode do objeto ws2 seja diferente do hashcode de ws1, então o objeto ws2 será inserido no HashSet também. Caso o hashcode de ws1 fosse igual ao hashcode de ws2, então o método equals seria chamado. Como a classe WrappedString não implementa o equals, será utilizado o equals da classe Object. Mas o equals da classe Object compara as referências dos objetos, que, neste caso, são diferentes. Então, mesmo que o hashcode de ws1 e ws2 sejam iguais, ws2 irá ser adicionado no HashSet pois o método equals irá retornar false.
Continuando, inserimos um objeto do tipo String (hs.add(s1) ). O hashcode chamado para o objeto s1 será o da classe String. Considerando que nem o hashcode de ws1 e nem o hashcode de ws2 são iguais ao hashcode de s1, então s1 será inserido no conjunto HashSet. Porém, aqui entra a minha dúvida: caso o hashcode de s1 fosse igual ao hashcode de ws1 por exemplo, o método equals seria utilizado. Mas desta vez, o método equals que será utilizado será o da classe String, pois o objeto (s1) que está sendo inserido é o da classe String. Assim, quando internamente s1 fosse comparado com ws1 ocorreria uma exceção! (por causa do cast inválido de WrappedString para String).
Esse caso não pode ocorrer? Caso esse caso ocorresse, então a alternativa G também estaria correta!!!
Eu errei em alguma parte do raciocínio?
