Duvida HashSet

3 respostas
Nykolas_Lima

Question 174
Click the Exhibit button.

import java.util.*;
class KeyMaster {
   public int i;
   public KeyMaster(int i) { this.i = i; }
   public boolean equals(Object o) { return i == ((KeyMaster)o).i; }
   public int hashCode() { return i; }
}
public class MapIt {
   public static void main(String[] args) {
      Set<KeyMaster> set = new HashSet<KeyMaster>();
      KeyMaster k1 = new KeyMaster(1);
      KeyMaster k2 = new KeyMaster(2);
      set.add(k1); set.add(k1);
      set.add(k2); set.add(k2);
      System.out.print(set.size() + ?:?);
      k2.i = 1;
      System.out.print(set.size() + ?:?);
      set.remove(k1);
      System.out.print(set.size() + ?:?);
      set.remove(k2);
      System.out.print(set.size());
   }
}[/code]

What is the result?
A. 4:4:2:2
B. 4:4:3:2
C. 2:2:1:0
D. 2:2:0:0
E. 2:1:0:0
F. 2:2:1:1
G. 4:3:2:1

Answer: F

Alguem poderia me explicar o porque de F?

para mim a resposta seria a C.

Valeu

3 Respostas

ViniGodoy

Bem... esse é o tipo de coisa que duvido que caia numa prova, pois é uma questão mal escrita e mal intencionada.

Você não pode alterar o valor retornado pelo hashCode de um objeto, depois dele estar adicionado num HashSet ou ser chave de um HashMap. O mapa se perde e o comportamento torna-se indefinido. O resultado exato pode variar de implementação para implementação.

Analisemos:
public static void main(String[] args) {   
      Set&lt;KeyMaster&gt; set = new HashSet&lt;KeyMaster&gt;();   
      KeyMaster k1 = new KeyMaster(1);   
      KeyMaster k2 = new KeyMaster(2);   

      //Aqui, adicionou-se 2 vezes o k1. 
      //O set, por definição nos garante que k1 só será adicionado 1 vez, já que ambos tem o mesmo hashcode.
      set.add(k1); set.add(k1);   

      //O mesmo comentário acima vale para o k2
      set.add(k2); set.add(k2);   

      //Não surpreendente: retorna 2.
      System.out.print(set.size() + ":");   
      //Aqui vem a bobagem... o usuário alterou o valor de i e, portanto, o hashcode também.
      //O objeto não vai notificar o hashSet da mudança. Portanto, temos um k2 com hashCode 1 no 
      //local do hashCode 2. O set não vai magicamente saber dessa mudança.
      k2.i = 1;   

      //Como nada no set mudou (nenhum add ou remove chamado), o tamanho continua o mesmo: 2
      System.out.print(set.size() + ":");   

      //Agora pedimos para remover k1. O código vai até a posição de k1 e o remove. Ok.
      set.remove(k1);   

      //Tamanho 1. k1 foi removido.
      System.out.print(set.size() + ":");   

      //Pedimos para remover k2. Agora o set vai até a posição de??? k1. 
      //Pois o hashcode de k2 agora é um, graças a linha k2.i = 1. Não há nada para remover lá.
      set.remove(k2);   

      //O tamanho permanece 1.
      System.out.print(set.size());   
   }
Nykolas_Lima

Otima explicação.

Muito obrigado ViniGodoy

felipe.far

Putz, agora entendi porque estava dando erro no sistema.

Valeu!!

Criado 13 de março de 2009
Ultima resposta 23 de set. de 2011
Respostas 3
Participantes 3