2016-11-02 4 views
0

.txt 파일에서 읽은 데이터가 고유한지 확인하기 위해 HashSet을 사용하려고합니다.HashSet이 중복 항목을 모두 제거하지 않습니다.

다음은 샘플 데이터입니다.

999990 bummer 
999990 bummer 
999990 bummer 
999990 bummer 
99999 bummer 
999990 bummerr 

Java.io.File 및 Java.util.Scanner를 사용하여 읽히고 Term of Object로 저장됩니다.

용어로 읽기;

while (rawTerms.hasNextLine()){ 
    String[] tokens = rawTerms.nextLine().trim().split(delimiter); 
    if (tokens.length == 2) {    
     uniqueSet.add(new Term(Double.parseDouble(tokens[0]), tokens[1])); //add the term to set 
    } 
    else { 
     rawTerms.close(); 
     throw new Exception("Invalid member length: "+ tokens.length); 
    }   
} 

allTerms = new ArrayList<>(uniqueSet); //Covert set into an ArrayList 

Term class using Guava; 나는이 항목에서 저장되는 배열의 크기를 확인하는 테스트를 실행할 때

public Term(double weight, String theTerm){ 
    this.weight = weight; 
    this.theTerm = theTerm; 
} 


@Override 
public boolean equals(final Object obj) { 
    if (obj instanceof Term){ 
     final Term other = (Term) obj; 
     return Objects.equal(this.weight, other.weight) 
       && Objects.equal(this.theTerm, other.theTerm); 
    } 
    else { 
     return false; 
    } 
} 

@Override 
public String toString(){ 
    return toStringHelper(this).addValue(weight) 
      .addValue(theTerm).toString(); 

} 

@Override 
public int hashCode() { 
    return Objects.hashCode(this.weight, this.theTerm); 
} 

그러나, 내가 목표로하고 3 개 항목 대신 1을 얻는다. 이전에 추가 된 항목과 동일한 가중치 또는 용어를 사용하여 새로운 항목을 복제본으로 간주합니다.

모든 도움을 주실 수 있습니다!

매트

+0

'고유 집합'이란 무엇입니까? – talex

+0

서식이 매우 불안정합니다. 게시하기 전에 IDE에서 자동 서식을 지정하십시오. 형식이 일관성을 유지하는지 확인하십시오. 또한 자바에서는 이집트 괄호가 선호됩니다. 마지막으로,'return'을 가지고 있다면'else'가 필요 없습니다. –

+0

@BoristheSpider 나는 애굽에 가본 적이 없으며 브래킷을 가져 오지도 않았지만 지금은 여러 해 동안 프로그래밍 해왔다. 옆으로 키우는 것, 나는 중괄호가 이집트 사람들 앞에서 다른 사람들의 생각에서 원하는 생각을 불러 일으킬 것이라고 생각합니다. :) –

답변

11

이전에 추가 한 항목과 동일한 가중치 또는 용어를 사용하여 새로운 항목을 복제본으로 간주합니다.

평등이 작동하지 않습니다. 평등은 이어야합니다. - x.equals(y)이 true를 반환하고 y.equals(z)이 true를 반환하면 x.equals(z)이 true를 반환해야합니다.

원하는 관계가 맞지 않습니다. 그것은 또한 아니다

주 어떤 순간에 당신의 equals 방법 검사 :

에만 true를 반환
return Objects.equal(this.weight, other.weight) 
    && Objects.equal(this.theTerm, other.theTerm); 

경우 동등 관계에 대한 정상 체중 용어 일치. 그것이 세트에 3 개의 엔트리를 가져 오는 이유입니다. 그런 식으로 보았을 때, 에 세 개의 서로 다른 엔티티가 있기 때문입니다.

기본적으로 HashSet과 평등을 다루는 다른 모든 컬렉션은 간단한 방식으로 도움이되지 않습니다.무게

  • 항목의 측면
  • 세트 (또는 목록)의 세트의

    • 집합 : 세 가지 별도의 컬렉션을해야합니다. 당신이 고려하고있는 항목이 무게 또는 용어 집합의 용어의 세트의 무게가있는 경우

    , 당신은 그것을 생략한다 - 그렇지 않으면, 당신은 세 가지 컬렉션의 각 항목을 추가한다 .

  • +0

    그런 다음 항목 집합이 간단한 목록이 될 수 있습니다. –

    +0

    @MarkoTopolnik : 참으로. 나는 그걸 추가할지 안할지 잘 모르겠다 ... 약간 편집 할 것이다. –

    +0

    "Term"에 대해 더 이상 정의 된 사용자 정의 동등성이 없기 때문에 각 인스턴스는 자체 등가 클래스에 있습니다. 따라서 세트는 오버 헤드 일뿐입니다. –

    6

    Term 클래스 hashCode (및 equals)의 구현을 고려, 당신은 관련된 쌍에 해당하는 3 개 항목을 기대한다 :

    999990 bummer 
    99999 bummer 
    999990 bummerr 
    

    모두 hashCodeequals 모두를 평가 쌍의 속성, 즉 weightdoubletheTermString이 있습니다.

    집합은 위에 나열된 3 가지 요소에 대해 서로 다른 해시 코드를 비교하여 부등식을 평가합니다.

    +0

    TS에 중복 된 질문이 있습니다. 당신의 대답은 그것이 일어나는 이유를 설명하지 못합니다. – talex

    +1

    OP가 얻으려는 내용에 대해서는 대답하지 않습니다. "이전에 추가 한 항목과 동일한 가중치 또는 용어를 사용하여 새로운 항목을 복제본으로 간주하고 싶습니다." –

    +0

    3 항목을 예상해야한다는 것을 알고 있습니다. 그러나, 나의 목표는 1 개의 유일한 입장을 위해있다. 아마도 @JonSkeet이 아래에서 제안한 (각각 별도의 컬렉션 사용) 내 문제를 해결할 것입니까? –