2012-11-06 114 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); 
      } 
    } 

注意我的映射器輸出格式與reducer相同,但reducer只是輸出最大值。

我失蹤了什麼

回答

3

您正在比較字符串而不是比較值。 「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是什麼,但你不應該從它創建字符串。提取整數並直接進行比較。

1

正確的方法是在這種情況下,平凡的方式:

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

IntWritable已經實現了Comparable接口的正確方法。

也就是說,你甚至可能不需要你的自定義比較類。

+0

這會給我的字典順序,這不是我想要的。 – fanbondi

+0

然後,在代碼中出現不同類型的錯誤。 「IntWritable」絕對不按字典順序排序。它甚至不包含字符串表示,而是一個原始的'int'。我的代碼**相當於你**(除了不按照字典順序排序)。 –