2013-05-06 4 views
3

이 코드 조각이 있다고 가정 해 보겠습니다.집합의 요소를 변경하면 '같음'의미가 변경됩니다.

public class HashAddAfter { 
    private class A { 
     public int value; 
     public A(int value) { 
      this.value = value; 
     } 
     public void setValue(int value) { 
      this.value = value; 
     } 
     // Code for hashCode()... 
     // Code for equals()... 
    } 

    Set<A> list1 = new HashSet<A>(); 
    Set<A> list2 = new HashSet<A>(); 

    public static void main(String[] args) { 
     HashAddAfter x = new HashAddAfter(); 

     A e1 = x.new A(1); 
     A e2 = x.new A(1); 

     x.list1.add(e1); 
     x.list2.add(e2); 

     System.out.println(x.list1.equals(x.list2)); // true 

     e1.setValue(4); 
     e2.setValue(4); 

     System.out.println(x.list1.equals(x.list2)); // false 
    } 
} 

나는 해시 코드() 인해 공간 제약에 등호()에 대한 코드를 삽입하지 않은,하지만 이클립스에서 생성 된 하나입니다.

문제는 두 세트의 요소를 변경하기 전에 세트가 동일하다는 것입니다. e1.hashCode() == e2.hashCode() 및 e1.equals (e2)가 있지만 값을 변경 한 후에 (각각 동일한 값으로 변경) 집합은 더 이상 동일하지 않습니다.

두 개의 HashSet을 비교할 때 Java는 요소의 원래 hashCode (삽입 순간의 코드)를 사용합니다. 따라서 삽입 후 요소를 변경하면 원래의 hashCode가 변경되므로 contains()가 false를 반환합니다.

내 의견으로는 이것은 매우 비 직관적 인 행동입니다.

당신은 어떻게 생각하십니까?

답변

2

이것은 정확히 예상되는 동작입니다. Set 구현에서 요소의 hashCode이 변경되었음을 인식 할 수있는 방법이 없으므로 해당 가능성을 방어하기 위해 수행 할 수있는 방법은 없습니다.

참고 : 다음 SetJavadoc에서

는 가변 객체가 세트 요소로서 사용되는 경우는주의를 기울여야한다. 오브젝트가 세트의 요소 인 동안 equals 비교에 영향을주는 방식으로 오브젝트의 값이 변경되면 세트의 작동은 지정되지 않습니다. 이 금지의 특별한 경우는 세트가 자신을 요소로 포함하는 것이 허용되지 않는다는 것입니다.

관련 문제