Читая немного вашего вопроса, я предполагаю, что вы видите странное поведение с java.util.HashSet
(обычно то, что все используют по умолчанию).
В контракте java.util.Set
можно получить один и тот же объект за java.util.HashSet
дважды, как это:
import java.util.HashSet;
import java.util.Set;
public class SetTest
{
public static void main(String[] args)
{
MyClass myObject = new MyClass(1, "testing 1 2 3");
Set<MyClass> set = new HashSet<MyClass>();
set.add(myObject);
myObject.setHashCode(2);
set.add(myObject);
System.out.println(set.size()); // this will print 2.
}
private static class MyClass
{
private int hashCode;
private String otherField;
public MyClass(int hashCode, String otherField)
{
this.hashCode = hashCode;
this.otherField = otherField;
}
public void setHashCode(int hashCode)
{
this.hashCode = hashCode;
}
public boolean equals(Object obj)
{
return obj != null && obj.getClass().equals(getClass()) && ((MyClass)obj).otherField.equals(otherField);
}
public int hashCode()
{
return hashCode;
}
}
}
После указателя от @jitter и взгляда на источник видно, почему это произошло.
Как говорит @jitter, java.util.HashSet
использует java.util.HashMap
внутри. Когда хэш изменяется между первым и вторым add , в java.util.HashMap
используется другой сегмент, и объект находится в наборе дважды.
Пример кода может показаться немного надуманным, но я видел, как это происходит в дикой природе с классами домена, где хеш создается из изменяемых полей, а метод equals не синхронизируется с этими полями.