zoukankan      html  css  js  c++  java
  • 自定义排序WritableComparable

      排序是MapReduce框架中重要的操作之一,其中MapTask和ReduceTask都会对数据按照key进行排序,这是Hadoop默认进行的操作。任何应用程序中的数据均会被排序,而不管逻辑上是否需要。一个MapReduce程序涉及了多种排序,而且相同类型的排序可能还进行了多次。其中,我们也可以自行定义排序来让MapReduce的处理结果达到我们想要的结果。而我们想要自定义排序,那就必须继承WritableComparable这个接口,看一下这个接口:

    public interface WritableComparable<T> extends Writable, Comparable<T> {
    }

      它继承了Writable接口和Comparable接口,由于WritableComparable中没有定义要实现的方法,所以继承这个接口,要实现的方法都是Writable接口和Comparable接口中的方法,它们主要有以下几个:

      对于Writable接口,要实现write和readFields方法,write是要对out对象进行序列化操作,readFields是对in对象进行反序列化操作。

    public interface Writable {
      /** 
       * Serialize the fields of this object to <code>out</code>.
       * 
       * @param out <code>DataOuput</code> to serialize this object into.
       * @throws IOException
       */
      void write(DataOutput out) throws IOException;
    
      /** 
       * Deserialize the fields of this object from <code>in</code>.  
       * 
       * <p>For efficiency, implementations should attempt to re-use storage in the 
       * existing object where possible.</p>
       * 
       * @param in <code>DataInput</code> to deseriablize this object from.
       * @throws IOException
       */
      void readFields(DataInput in) throws IOException;
    }

    Comparable接口,它的作用是将调用该方法的对象和传入参数对象进行比较:

    public int compareTo(T o);

    返回值有三种:负整数,此时调用该方法的对象小于指定对象;0,二者相等;正整数,调用该方法的对象大于指定对象。

      因为比较是针对key进行排序的,所以如果我们要想自定义对map处理后的数据排序,那么就应该map输出的数据中的key的类型应是我们自定义的,并且实现了WritableComparable接口,那么实现这个接口应该怎么写实现类呢,让我们看一下这个示例:

    public class MyWritableComparable implements WritableComparable<MyWritableComparable> {
       // Some data
       private int counter;
       private long timestamp;
    
       public void write(DataOutput out) throws IOException {
         out.writeInt(counter);
         out.writeLong(timestamp);
       }
    
       public void readFields(DataInput in) throws IOException {
         counter = in.readInt();
         timestamp = in.readLong();
       }
    
       public int compareTo(MyWritableComparable o) {
         int thisValue = this.value;
         int thatValue = o.value;
         return (thisValue &lt; thatValue ? -1 : (thisValue==thatValue ? 0 : 1));
       }
    
        public int hashCode() {
         final int prime = 31;
         int result = 1;
         result = prime * result + counter;
         result = prime * result + (int) (timestamp ^ (timestamp &gt;&gt;&gt; 32));
         return result
            }
     }

    注意,实现序列化和反序列化方法时,写入和读取属性的顺序一定要相同!!!实现完成之后,这个实现类就可以作为Map阶段输入或者输出数据的key类型,进行输出。要想自定义排序,最核心的逻辑代码就在compareTo方法中。

  • 相关阅读:
    Linux Core Dump【转】
    定位多线程内存越界问题实践总结【转】
    gcc __attribute__关键字举例之visibility【转】
    va_start(),va_end()函数应用【转】
    谁在call我-backtrace的实现原理【转】
    利用backtrace和ucontex定位segment错误【转】
    善用backtrace解决大问题【转】
    linux backtrace()详细使用说明,分析Segmentation fault【转】
    利用gcc自带的功能-fstack-protector检测栈溢出及其实现【转】
    Linux环境下段错误的产生原因及调试方法小结【转】
  • 原文地址:https://www.cnblogs.com/yxym2016/p/12993895.html
Copyright © 2011-2022 走看看