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);
            }
    }

请注意,我的映射器输出与减速器具有相同的格式,但减速器只是输出最大值。

我错过了什么

4

3 回答 3

3

您正在比较字符串而不是比较值。"10" < "2" 即使10> 2

您需要从 IntWritable 获取第一个字段或解析第一个数字并进行比较。

BTW:如果你要使用toString(),你不需要先转换它,因为都Object支持这种方法。

于 2012-11-06T12:57:29.873 回答
2

您正在比较字符串

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

你不应该这样做。而是比较数字。我不知道是什么IntWritable,但你不应该从中创建字符串。提取整数并直接比较它们。

于 2012-11-06T12:57:37.387 回答
1

在这种情况下,正确的方法是简单的方法:

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

IntWritable已经Comparable以正确的方式实现了接口。

也就是说,您甚至可能不需要自定义比较器类。

于 2012-11-06T13:10:31.927 回答