2012-11-06 5 views
0

내가 예를 들어 자연 순서로 정렬에 내 감속기변경 감속기 정렬 순서

Key   Value 
1 1998-01-05   45 
10 1998-01-09  20 
2 1998-01-06   68 
3 1998-01-07   85 
4 1998-01-08   85 

사 전적으로이 올바르지 만에서 다음과 같은 출력을 원했다

Key    Value 
1 1998-01-05   45 
2 1998-01-06   68 
3 1998-01-07   85 
4 1998-01-08   85 
10 1998-01-09  20 

나는 이것을 달성하기 위해 KeyComparator를 작성했으나 아래 코드가 있지만이 방법도 효과가 없었다.

public static class KeyComparator extends WritableComparator { 
      protected KeyComparator() { 
        super(IntWritable.class, true); 
      } 

      @SuppressWarnings("rawtypes") 
      public int compare(WritableComparable w1, WritableComparable w2) { 
        IntWritable t1 = (IntWritable) w1; 
        IntWritable t2 = (IntWritable) w2; 
        String t1Items = t1.toString(); 
        String t2Items = t2.toString(); 
        return t1Items.compareTo(t2Items); 
      } 
    } 

참고 내 매퍼 출력은 감속기와 동일한 형식이지만 감속기는 최대 값을 출력 중입니다.

무엇이 없습니까?

답변

3

값을 비교하는 대신 문자열을 비교합니다. "012"가 10>2인데도 "10"< "2"입니다.

IntWritable에서 첫 번째 필드를 가져 오거나 첫 번째 숫자를 파싱하여 비교해야합니다.

현재 : toString()을 사용하려는 경우 먼저 Object이이 메서드를 지원하므로 먼저 캐스팅 할 필요가 없습니다.

+0

이제는 올바른 순서로 정렬되지만 동일한 정수로 시작하는 다른 키는 삭제됩니다. 예 : 1 1998-01-05 45, 1 1998-01-05 46; 그것은 첫 번째를 버리고 두 번째를 유지합니다. 무슨 일이 일어날 지 아십니까? – fanbondi

+0

SortedMap 또는 SortedSet을 사용하는 경우 중복을 무시합니다. 해결 방법은 List를 사용하고 Collections.sort()로 정렬하는 것입니다. –

2

당신은 비교하는 문자열

   String t1Items = t1.toString(); 
       String t2Items = t2.toString(); 
       return t1Items.compareTo(t2Items); 

당신은이 작업을 수행해서는 안된다. 대신 숫자를 비교하십시오. 나는 IntWritable이 무엇인지 모르지만 그걸로 문자열을 만들어서는 안됩니다. 정수를 추출하고 직접 비교하십시오.

public int compare(WritableComparable w1, WritableComparable w2) { 
    return w1.compareTo(w2); 
} 

IntWritable 이미 Comparable 인터페이스에게 적절한 방법을 구현

1

올바른 방법은이 경우에 사소한 방법이다.

즉, 사용자 지정 비교기 클래스가 필요하지 않을 수도 있습니다.

+0

이것은 내가 원한 것이 아닌 사전 작문 순서를 줄 것이다. – fanbondi

+0

그런 다음 코드에 다른 종류의 오류가 있습니다. 'IntWritable'은 사전 적으로 정렬하지 않습니다. 그것은 문자열 표현을 포함하지 않지만 원시적 인 'int'를 포함합니다. 내 코드는 ** 네 코드와 동등합니다 ** (사전 적으로 정렬하지 않는 경우 제외). –