2010-04-20 6 views
2

개체 목록이 포함 된 목록이 있는데이 목록에서 해당 특성 중 두 가지 값이 같은 모든 요소를 ​​제거하고 싶습니다. 나는했다하지만이 같은 일을 대한 :해시 메서드를 재정의하지 않고 중복 제거

List<Class1> myList; 
.... 
Set<Class1> mySet = new HashSet<Class1>(); 
mySet.addAll(myList); 

및 오버라이드 (override) 해시 방법을 클래스 1에 그것은 단지 내가 고려해야 할 속성에 따라 숫자를 반환 있도록.

문제는이 방법으로 해시 메서드를 재정의 할 수 없도록 응용 프로그램의 다른 부분에서 다른 필터링을 수행해야한다는 것입니다. 두 가지 해시 메서드가 필요합니다.

해시 방법을 재정의하지 않고이 필터링을 수행하는 가장 효율적인 방법은 무엇입니까?

감사

+0

@Bark K. 아니요, 두 클래스를 만들 수는 없지만 동일한 클래스인지, 다른 관점에서 볼 때 동일한 객체인지 아닌지를 결정하기 위해 여러 정보를 고려해야합니다. 사실 hash() 메서드 중 어느 것도 올바르지 않을 것입니다. 트릭을 만드는 것이 좋을 것이므로 좋은 습관이 아닙니다. 그런 이유로 저는 해시 방법을 고려하지 않은 것을 사용하고 싶었습니다. – Javi

+0

명확성을 위해 : 최종 '세트'에 attr1과 attr2의 값이 동일한 인스턴스가 두 개 필요하지 않습니까? – DJClayworth

+0

@ DJClayworth 정확히, 그게 – Javi

답변

4

hashCodeequalsClass1 (이 작업을하기 위해)로 변경하는 것은 문제가 있습니다. 당신은 평등에 대한 부자연스럽지 않은 정의를 가진 당신의 수업으로 끝나게됩니다. 그것은 다른 현재 그리고 미래의 수업 사용을 위해 다른 것으로 밝혀 질 것입니다.

Comparator 인터페이스를 검토하고 Comparator<Class1> 구현을 작성하여 기준에 따라 Class1의 인스턴스를 비교하십시오. 예 : 이 두 속성을 기반으로합니다. 그런 다음 TreeSet(Comparator) 생성자를 사용하여 중복 검색을 위해 TreeSet<Class을 인스턴스화하십시오.

편집

@ 톰 Hawtin의의 접근이 접근 방식을 비교 :

  • 두 가지 접근 방법은 전체 대략 비슷한 공간을 사용합니다. 트리 집합의 내부 노드는 해시 집합의 배열과 사용자 지정 같음/해시 방법을 지원하는 래퍼의 대략적인 균형을 유지합니다.

  • 래퍼 + 해시 세트 접근 방식은 시간상 (해싱이 좋다고 가정 할 때) 일 때 트리 집합 접근 방식에 대해 O(N)입니다. 입력 목록이 커질 가능성이있는 경우이를 수행하는 방법입니다.

  • 트리 집합 접근법은 작성해야하는 코드 행의 관점에서 승리합니다.

3

Class1 구현 Comparable을 보자. 귀하의 예처럼 TreeSet을 사용하십시오 (예 : addAll 방법 사용).

+1

TreeSet 또한 나의 첫 번째 생각이었다. 비록 Comparable을 구현하지 않아도됩니다. TreeSet 생성자에서 사용자 정의 콤퍼레이터를 사용하면이 작업을위한 완벽한 도구가됩니다. – extraneon

1

이 컨텍스트에서 중요한 것으로 생각하고 싶은 부분을 Class1의 개념으로 소개하는 것이 좋습니다. 그런 다음 HashSet 또는 HashMap을 사용하십시오.

+0

해시는 이미 다른 곳에서 사용되고있는 문제를 이해하고 있으며 필터링은 다른 맞춤 매개 변수에서 수행해야합니다. – extraneon

+0

@extraneon : 다른 수업을 소개 할 것을 제안합니다. –

2

로마가 말한 것에 대한 대안으로 표현식을 사용하여 필터링에 대해 this SO question을 살펴볼 수 있습니다. 어쨌든 Google Collections를 사용하는 것이 좋을 것 같습니다.

+0

+1 - GC 라이브러리는 필터링 된보기 만 필요한 경우 특히 효과적입니다. – Carl

0

때때로 프로그래머는 언어의 멋진 기능을 모두 사용하려고 너무 복잡하게 만들고이 질문에 대한 대답을 예로들 수 있습니다. 클래스에있는 모든 것을 재정의하면 잔인합니다.필요한 것은 다음과 같습니다.

class MyClass { 
    Object attr1; 
    Object attr2; 
} 

List<Class1> list; 
Set<Class1> set=.... 
Set<MyClass> tempset = new HashSet<MyClass>; 

for (Class1 c:list) { 
    MyClass myc = new MyClass(); 
    myc.attr1 = c.attr1; 
    myc.attr2 = c.attr2; 

    if (!tempset.contains(myc)) { 
    tempset.add(myc); 
    set.add(c); 
    } 
} 

작은 불규칙성을 고칠 수 있습니다. 속성에 대한 평등의 의미 (속성이 원시적 인 경우 명백한 변경)에 따라 몇 가지 문제가 있습니다. 때로는 내장 라이브러리를 사용하는 것뿐만 아니라 코드를 작성해야 할 때도 있습니다.