调用compareTo()和调用原始/自定义比较器的compare()方法时,键如何排序?

时间:2018-08-13 13:58:41

标签: hadoop

Consider this class: (From Hadoop: The definitive guide 3rd edition):

    import java.io.*;
    import org.apache.hadoop.io.*;

    public class TextPair implements WritableComparable<TextPair> {

      private Text first;
      private Text second;

      public TextPair() {
        set(new Text(), new Text());
      }

      public TextPair(String first, String second) {
        set(new Text(first), new Text(second));
      }

      public TextPair(Text first, Text second) {
        set(first, second);
      }

      public void set(Text first, Text second) {
        this.first = first;
        this.second = second;
      }

      public Text getFirst() {
        return first;
      }

      public Text getSecond() {
        return second;
      }

      @Override
      public void write(DataOutput out) throws IOException {
        first.write(out);
        second.write(out);
      }

      @Override
      public void readFields(DataInput in) throws IOException {
        first.readFields(in);
        second.readFields(in);
      }

      @Override
      public int hashCode() {
        return first.hashCode() * 163 + second.hashCode();
      }

      @Override
      public boolean equals(Object o) {
        if (o instanceof TextPair) {
          TextPair tp = (TextPair) o;
          return first.equals(tp.first) && second.equals(tp.second);
        }
        return false;
      }

      @Override
      public String toString() {
        return first + "\t" + second;
      }

      @Override
      public int compareTo(TextPair tp) {
        int cmp = first.compareTo(tp.first);
        if (cmp != 0) {
          return cmp;
        }
        return second.compareTo(tp.second);
      }
      // ^^ TextPair

      // vv TextPairComparator
      public static class Comparator extends WritableComparator {

        private static final Text.Comparator TEXT_COMPARATOR = new Text.Comparator();

        public Comparator() {
          super(TextPair.class);
        }

        @Override
        public int compare(byte[] b1, int s1, int l1,
                           byte[] b2, int s2, int l2) {

          try {
            int firstL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1);
            int firstL2 = WritableUtils.decodeVIntSize(b2[s2]) + readVInt(b2, s2);
            int cmp = TEXT_COMPARATOR.compare(b1, s1, firstL1, b2, s2, firstL2);
            if (cmp != 0) {
              return cmp;
            }
            return TEXT_COMPARATOR.compare(b1, s1 + firstL1, l1 - firstL1,
                                           b2, s2 + firstL2, l2 - firstL2);
          } catch (IOException e) {
            throw new IllegalArgumentException(e);
          }
        }
      }

      static {
        WritableComparator.define(TextPair.class, new Comparator());
      }
      // ^^ TextPairComparator

      // vv TextPairFirstComparator
      public static class FirstComparator extends WritableComparator {

        private static final Text.Comparator TEXT_COMPARATOR = new Text.Comparator();

        public FirstComparator() {
          super(TextPair.class);
        }

        @Override
        public int compare(byte[] b1, int s1, int l1,
                           byte[] b2, int s2, int l2) {

          try {
            int firstL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1);
            int firstL2 = WritableUtils.decodeVIntSize(b2[s2]) + readVInt(b2, s2);
            return TEXT_COMPARATOR.compare(b1, s1, firstL1, b2, s2, firstL2);
          } catch (IOException e) {
            throw new IllegalArgumentException(e);
          }
        }

        @Override
        public int compare(WritableComparable a, WritableComparable b) {
          if (a instanceof TextPair && b instanceof TextPair) {
            return ((TextPair) a).first.compareTo(((TextPair) b).first);
          }
          return super.compare(a, b);
        }
      }
      // ^^ TextPairFirstComparator

    // vv TextPair
    }
    // ^^ TextPair  
  

1。如果我们未实现自定义比较器类,则键为
    是根据TextPair类中定义的compareTo方法排序的,不是吗?

     

2。当原始的自定义比较器类-比较器例如定义为
    如上所见,我了解该方法     比较(字节[] b1,整数s1,整数l1,字节[] b2,整数s2,整数l2)     我们在设置原始Comparator类时将在排序时调用
    对于静态块下面的TextPair。它是否正确 ?

     

**静态{
        WritableComparator.define(TextPair.class,new Comparator());
      } **

     

3。在方法内部,      compare(byte [] b1,int s1,int l1,byte [] b2,int s2,int l2)     在下面看到的行中,Text.Comparator类的比较方法称为吗?

     

int cmp = TEXT_COMPARATOR.compare(b1,s1,firstL1,b2,s2,firstL2);

     

4. 比较(byte [] b1,int s1,int l1,byte [] b2,int s2,int l2)     当我们不想执行密钥的反序列化时很有用     对象在排序时是不是?

     
      
  1. 何时调用自定义比较器,因为没有静态块
      像下面为原始自定义比较器定义的代码一样?
      静态{
      WritableComparator.define(TextPair.class,new Comparator());   }

  2.   
  3. 定义自定义比较器类(即FirstComparator)后,我们
      定义比较WritableComparable a,WritableComparable b
      用与自然排序不同的排序顺序对键进行排序的方法   订购。那么什么时候调用此方法?

  4.   
  5. WritableComparator接口的javadocs表示默认
      以下方法的实现

         

    public int compare(byte [] b1,                      int s1,                      int l1,                      字节[] b2,                      int s2,                      int l2)

         

    将数据读取到两个WritableComparables中(使用 Writable.readFields
      (DataInput)
    ,然后调用 compare(WritableComparable,WritableComparable)   但是当使用FirstComparator作为TextPair类的比较器时,   排序机制如何知道应调用哪种比较方法,   比较(字节[] b1,整数s1,整数l1,字节[] b2,整数s2,整数l2)   或比较WritableComparable a,WritableComparable b,因为我们覆盖了两者   自定义比较器类中的方法?

  6.   

0 个答案:

没有答案