在前面的博文《Hadoop中WritableComparable 和 comparator》中,對於WritableComparator說的不夠細致,下面說說具體的實現原理!
1.WritableComparator主要提供了兩個功能:
- 提供了對原始compara()方法的一個默認實現,默認實現是先反序列化成對象,在對對象進行比較
1 public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) { 2 3 try { 4 5 buffer.reset(b1, s1, l1); // parse key1 6 7 key1.readFields(buffer); 8 9 10 11 buffer.reset(b2, s2, l2); // parse key2 12 13 key2.readFields(buffer); 14 15 16 17 } catch (IOException e) { 18 19 throw new RuntimeException(e); 20 21 } 22 23 24 25 return compare(key1, key2); // compare them 26 27 }
而對應的基礎數據類型的compare()的實現卻巧妙的利用了特定類型的泛化:(利用了writableComparable的compareTo方法)
1 public int compare(WritableComparable a, WritableComparable b) { 2 3 return a.compareTo(b); 4 5 }
- 充當RawComparator的注冊工廠,通過get()方法,得到實例。
在WritableComparator中,private static HashMap<Class, WritableComparator>comparators =new HashMap<Class, WritableComparator>();記載着RawComparator實例,例如,可以通過下面的代碼,獲得一個IntWritable類型的RawComparator。
RawComparator<IntWritable> writable = WritableComparator.get(IntWritable.class);
2.WritableComparator如何注冊定制的Writable
在WritableComparator類中,有一個方法define,通過該方法,可以將Writable注冊到WritableComparator,以便可以通過get方法,直接獲得實例!
1 public static synchronized void define(Class c,WritableComparator comparator) { 2 comparators.put(c, comparator); 3 }
3.BooleanWritable中內置Comparator的實現
WritableComparable的各種實例,例如 IntWritable實例:內部類Comparator類需要根據自己的IntWritable類型重載WritableComparator里面的compare()方法,可以說WritableComparator里面的compare()方法只是提供了一個缺省的實現,而真正的compare()方法實現需要根據自己的類型如IntWritable進行重載,所以WritableComparator方法中的那些readInt..等方法只是底層的封裝的一個實現,方便內部Comparator進行調用而已。
下面我們着重看下BooleanWritable類的內置RawCompartor<T>的實現過程:
1 ** 2 * A Comparator optimized for BooleanWritable. 3 */ 4 public static class Comparator extends WritableComparator { 5 public Comparator() {//調用父類的Constructor初始化keyClass=BooleanWrite.class 6 super(BooleanWritable.class); 7 } 8 //重寫父類的序列化比較方法,用些類用到父類提供的缺省方法 9 public int compare(byte[] b1, int s1, int l1, 10 byte[] b2, int s2, int l2) { 11 boolean a = (readInt(b1, s1) == 1) ? true : false; 12 boolean b = (readInt(b2, s2) == 1) ? true : false; 13 return ((a == b) ? 0 : (a == false) ? -1 : 1); 14 } 15 } 16 //注冊 17 static { 18 WritableComparator.define(BooleanWritable.class, new Comparator()); 19 }