2016-05-05 3 views
0

Это своего рода дубликат this question,, однако я ищу немного больше объяснений ELI5 о «изменяемых ключах» и «ведрах» в ответах.Как изменить значения в HashSet?

Вот мой код, что у меня трудности с пониманием:

HashSet<Object> set = new HashSet<Object>(); 
    set.add(1); set.add(2); set.add(3); 

    for(Object i : set) 
     if(i.equals(1)) { 
      i = 1337; 
      System.out.println("FOUND"); 
     } 

    for(Object i : set) System.out.println(i); 

выход:

FOUND 

1 

2 

3 

Почему это не распечатайте 1337, 2, 3 вместо этого?

Этот же вопрос касается удаления объектов.

EDIT:

Это делает то, что я хочу, но я абсолютно уверен, его не правильный путь идти о нем:

for(Object i : set) 
     if(i.equals(1)) { 
      set.remove(i); 
      set.add(1337); 
      break; 
     } 
+0

Все дело в том, что нельзя назначать ссылки в цикле for-each и не имеет ничего общего с изменяемыми или не изменяемыми ключами. Переменная i - временная ограниченная переменная области видимости, и изменение ее назначения не будет влиять на содержимое переработанной коллекции. –

+0

@HovercraftFullOfEels, понимая, что это был очень глупый вопрос ... –

ответ

1

Вы обрабатываете примитивы здесь. Что вы делаете в цикле for, вы копируете значение от Set до i, а затем вы делаете что-то с этим. Теперь i - это совершенно новая переменная, и вы изменили ее значение, а не на Set. Поэтому Set не изменился. Таким образом, вы должны удалить его из Set, а затем положить новое значение, делая это OK:

for(Object i : set) 
     if(i.equals(1)) { 
      set.remove(i); 
      set.add(1337); 
      break; 
     } 

То же самое произойдет, если у вас есть объекты, вы будете иметь новый указатель, а не один и тот же объект, но два указателя, указывающие на в том же месте, поэтому вы удаляете один указатель, но один из Set останется, поэтому GC не удалит объект, пока указатель в Set не будет удален (поэтому указатели не указывают на объект).

0

Когда вы делаете set.remove(i) & set.add(i) он будет работать так как вы выполняете операцию на множестве.

Но когда вы делаете i=1337, вы просто присваиваете значение переменной i и не выполняете какую-либо заданную операцию.