Reputation: 1047
I have the following output from my reducer
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
Lexicographically this is correct but I want it to sorted in Natural order e.g.
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
I wrote a KeyComparator to achieve this and below is the code but even this did not work out.
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);
}
}
Note my mapper output have the same format as the reducer but reducer is just outputting the maximum value.
What am I missing
Upvotes: 0
Views: 533
Reputation: 200266
The correct way is the trivial way in this case:
public int compare(WritableComparable w1, WritableComparable w2) {
return w1.compareTo(w2);
}
IntWritable
already implements the Comparable
interface the proper way.
That said, you may not even need your custom comparator class.
Upvotes: 1
Reputation: 115388
You are comparing strings
String t1Items = t1.toString();
String t2Items = t2.toString();
return t1Items.compareTo(t2Items);
You should not do this. Compare the numbers instead. I have no idea what IntWritable
is but you should not create string from it. Extract integers and compare them directly.
Upvotes: 2
Reputation: 533820
You are comparing Strings instead of comparing values. "10" < "2" even though 10
> 2
.
You need to get the first field from your IntWritable or parse the first number and compare it.
BTW: If you are going to use toString()
, you don't need to cast it first as all Object
support this method.
Upvotes: 3