2015-02-01 3 views
1

HashSet에서 중복이 허용되는 것처럼 보입니다. 이유는 무엇입니까, 어떻게 제거하려고합니까? 그리고 두 번째 remove()이 아래에서 작동하지 않는 이유는 무엇입니까? 모든 중복을 제거하는 한 가지 방법은 new HashSet<>(set)이지만 새 개체를 만드는 것을 포함하지 않는 더 좋은 방법이 있습니까?java HashSet에서 중복 됨

Set<ArrayList<String>> set = new HashSet<>(); 
ArrayList<String> a1 = new ArrayList<>(); 
ArrayList<String> a2 = new ArrayList<>(); 

a1.add("a"); 
set.add(a1); 
a1.remove("a"); 

set.add(a2); 

System.out.println(set.size()); 
System.out.println(set); 

ArrayList<String> a3 = new ArrayList<>(); 
for (Object o : set) { 
    boolean b = o.equals(a3) && (o.hashCode() == a3.hashCode()); 
    if (!b) System.out.println(false); 
} 

set.remove(new ArrayList<String>()); 
System.out.println(set); 
set.remove(new ArrayList<String>()); 
System.out.println(set); 
set.remove(set.iterator().next()); 
System.out.println(set); 
System.out.println(set.iterator().next() == a1); 

출력 : set이 동일한 두 개의 빈 목록, 초기에 제거 할 수 없습니다 빈 없었던 일로 구성되어 있습니다.

2 
[[], []] 
[[]] 
[[]] 
[[]] 
true 
+0

을 또는 필요가 ... – fge

답변

3

해싱은 버킷 삽입시 삽입 시간에 발생합니다. 나중에 오브젝트를 변경하면 해시 코드가 변경되지만 이미 해당 버킷에있을 것입니다. 삽입하는 데 사용한 해시 코드와 다른 해시 코드로 검색하려고하기 때문에 (직접) 검색 할 수 없습니다. 요소가 HashMap에 저장된다

a1.add("a"); 
set.add(a1); // hashed and bucketed 
a1.remove("a"); // hash code changes but doesn't affect set 

set.add(a2); // hashes to a different place than a1 
6

위치는 첨가시에 그 요소의 hashCode에 의존한다.

요소를 추가 한 후 hashCode가 변경되는 요소의 속성을 변경하는 경우 (ArrayList 요소의 경우 목록에서 요소를 제거하면 해당 요소가 정확하게 삭제됩니다), HashSet (또는 제거)은 실패합니다.

1

지도 또는지도 요소의 키를 수정하면 효과적으로 손상됩니다. 컬렉션이 요소를 변경했는지 또는 올바르게 처리했는지 알 수있는 방법이 없습니다. 당신이 키 또는 요소를 수정하려면

먼저 "불변 클래스의 유용성", 제거를 수정하고 다시 추가합니다.