5.3.3 自定义writable

(1)构造员工writable

Hadoop虽然已经实现了一些非常有用的Writable,而且你可以使用他们的组合做很多事情,但是如果你想构造一些更加复杂的结果,你可以自定义Writable来达到你的目的,例如员工writable有姓名和角色两个Text属性构成,需要对员工writable姓名和角色同时进行比较排序。定义类实现WritableComparable接口,、实现构造函数、属性getset函数,readfield和write函数、compareTo函数用于比较、toString()函数实现字符串输出。

https://blog.csdn.net/lzm1340458776/article/details/42675433

/**

* 自定义Writable通常都要实现Writable接口

* 如果有比较大小的业务,最好是实现WritableComparable接口

* time : 2015年1月13日下午1:39:12

* @version

*/

public class EmployeeWritable implements WritableComparable<EmployeeWritable>{

//姓名

private Text name;

//角色

private Text role;

//必须提供无参构造方法(一定要创建name和role对象否则会报空指针异常)

public EmployeeWritable() {

name = new Text();

role = new Text();

}

//构造函数

public EmployeeWritable(Text name, Text role) {

this.name = name;

this.role = role;

}

public Text getName() {

return name;

}

public void setName(Text name) {

this.name = name;

}

public Text getRole() {

return role;

}

public void setRole(Text role) {

this.role = role;

}

/**

* 调用成员对象本身的readFields()方法,从输入流中反序列化每一个成员对象

*/

public void readFields(DataInput dataInput) throws IOException {

name.readFields(dataInput);

role.readFields(dataInput);

}

/**

* 通过成员对象本身的write方法,序列化每一个成员对象到输出流中

*/

public void write(DataOutput dataOutput) throws IOException {

name.write(dataOutput);

role.write(dataOutput);

}

/**

* 如果实现了WritableComparable接口必须实现compareTo方法,用于比较,需要反序列化对象得到text然后比较

*/

public int compareTo(EmployeeWritable employeeWritable) {

int cmp = name.compareTo(employeeWritable.name);

//如果不相等

if (cmp != 0){

return cmp;

}

//如果名字相等就比较角色

return role.compareTo(employeeWritable.role);

/**

* MapReduce需要一个分割者(Partitioner)把Map的输出作为输入分成一块块的喂给多个reduce

* 默认的是HashPatitioner,它是通过对象的hashCode函数进行分割。

* 所以hashCode的好坏决定了分割是否均匀,它是一个很关键的方法

*/

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + ((name == null) ? 0 : name.hashCode());

result = prime * result + ((role == null) ? 0 : role.hashCode());

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

EmployeeWritable other = (EmployeeWritable) obj;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

if (role == null) {

if (other.role != null)

return false;

} else if (!role.equals(other.role))

return false;

return true;

}

/**

* 自定义自己的输出类型

*/

@Override

public String toString() {

return "EmployeeWritable [姓名=" + name + ", 角色=" + role + "]";

}

}

(2)自定义RawComparatorWritable

上面的EmployeeWritable, MapReduce里的key,需要进行比较时,首先要反序列化成一个对象,然后再调用compareTo对象进行比较,但是这样效率太低了,可以直接通过序列化之后的数值进行比较,来提高效率直接根据序列化之后的值进行比较排序,我们只需要把EmployeeWritable序列化后的结果拆分为成员对象,然后比较成员对象即可,看代码:

public static class Comparator extends WritableComparator{

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

protected Comparator() {

super(EmployeeWritable.class);

}

//b1是对象a的序列化字节,s1是name的偏移量,l1是总长度

@Override

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

try {

// /**

* Text是标准的UTF-8字节流,

* 由一个变长整形开头表示Text中文本所需要的长度,接下来就是文本本身的字节数组

* decodeVIntSize返回变长 整形的长度,readVInt 表示 文本字节数组的长度,加起来就是第一个成员name的长度*/

int nameL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1);

int nameL2 = WritableUtils.decodeVIntSize(b2[2]) + readVInt(b2, s2);

//和compareTo方法一样,先比较name

int cmp = TEXT_COMPARATOR.compare(b1, s1, nameL1, b2, s2, nameL2);

if (cmp != 0){

return cmp;

}

//再比较role

return TEXT_COMPARATOR.compare(b1, s1+nameL1, l1-nameL1, b2, s2+nameL2, l2-nameL2);

} catch (Exception e) {

throw new IllegalArgumentException();

}

}

static {

//注册raw comparator,更像是绑定,这样MapReduce使用EmployeeWritable时就会直接调用Comparator

WritableComparator.define(EmployeeWritable.class, new Comparator());

}

}

5.3.3 自定义writable和RawComparatorWritable的更多相关文章

  1. 自定义Writable、RawComparatorWritable、comparators(转)

    自定义Writable hadoop虽然已经实现了一些非常有用的Writable,而且你可以使用他们的组合做很多事情,但是如果你想构造一些更加复杂的结果,你可以自定义Writable来达到你的目的,我 ...

  2. 读取SequenceFile中自定义Writable类型值

    1)hadoop允许程序员创建自定义的数据类型,如果是key则必须要继承WritableComparable,因为key要参与排序,而value只需要继承Writable就可以了.以下定义一个Doub ...

  3. Hadoop Serialization -- hadoop序列化详解 (3)【ObjectWritable,集合Writable以及自定义的Writable】

    前瞻:本文介绍ObjectWritable,集合Writable以及自定义的Writable TextPair 回顾: 前面了解到hadoop本身支持java的基本类型的序列化,并且提供相应的包装实现 ...

  4. 自定义排序及Hadoop序列化

    自定义排序 将两列数据进行排序,第一列按照升序排列,当第一列相同时,第二列升序排列. 在map和reduce阶段进行排序时,比较的是k2.v2是不参与排序比较的.如果要想让v2也进行排序,需要把k2和 ...

  5. MapReduce实例-倒排索引

    环境: Hadoop1.x,CentOS6.5,三台虚拟机搭建的模拟分布式环境 数据:任意数量.格式的文本文件(我用的四个.java代码文件) 方案目标: 根据提供的文本文件,提取出每个单词在哪个文件 ...

  6. 重新认识mapreduce

    写这篇文章,是因为最近遇到了mapreduce的二次排序问题.以前的理解不完全正确.首先看一下mapreduce的过程 相信这张图熟悉MR的人都应该见过,再来一张图 wordcount也不细说了,ha ...

  7. [大牛翻译系列]Hadoop(13)MapReduce 性能调优:优化洗牌(shuffle)和排序阶段

    6.4.3 优化洗牌(shuffle)和排序阶段 洗牌和排序阶段都很耗费资源.洗牌需要在map和reduce任务之间传输数据,会导致过大的网络消耗.排序和合并操作的消耗也是很显著的.这一节将介绍一系列 ...

  8. 一站式Hadoop&Spark云计算分布式大数据和Android&HTML5移动互联网解决方案课程(Hadoop、Spark、Android、HTML5)V2的第一门课程

    Hadoop是云计算的事实标准软件框架,是云计算理念.机制和商业化的具体实现,是整个云计算技术学习中公认的核心和最具有价值内容. 如何从企业级开发实战的角度开始,在实际企业级动手操作中深入浅出并循序渐 ...

  9. [BigData]关于Hadoop学习笔记第三天(PPT总结)(一)

     课程安排 MapReduce原理*** MapReduce执行过程** 数据类型与格式*** Writable接口与序列化机制*** ---------------------------加深拓展- ...

随机推荐

  1. matlab cell

    cell元包是matlab中提供的一种数据类型,功能强大. 关于cell的创建: 1.跟一般创建举证一样,直接使用C = {A B D E}这种形式,不过这里把"[]"改成了}&q ...

  2. ROUTE: route addition failed

    ROUTE: route addition failed 1)报FlushIpNetTable failed on interface错误 应对:以管理员身份运行OpenV-P-N 2)报Warnin ...

  3. [NOIP2018模拟赛10.23]发呆报告

    闲扯 考场看了眼题目感觉很难,一个小时敲完了所有暴力...嗯然后就在那里发呆什么事也没做 T3考场上把数据结构想了个遍都不会完成1操作,现在看这种思路其实之前也接触过... 比较玄学的一件事情就是T1 ...

  4. 伪元素before和after本质

    之所以被称为伪元素,是因为他们不是真正的页面元素,html没有对应的元素,但所有的用法和表现行为和真正的页面元素是一样的,可以对其使用诸如页面元素一样的css样式,表面上看上去貌似页面的谋些元素,实际 ...

  5. mysql 创建用户,授权,查询用户等

    MySQL创建用户与授权 一. 创建用户 命令: CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明: username:你将创建的用 ...

  6. 【SQL server】SQL server基础(二)

    一.一些重要的SQL命令 SELECT - 从数据库中提取数据 UPDATE - 更新数据库中的数据 DELETE - 从数据库中删除数据 INSERT INTO - 向数据库中插入新数据 CREAT ...

  7. RT-Thread--简介

    RT-Thread 概述 RT-Thread,全称是 Real Time-Thread,它是一个嵌入式实时多线程操作系统,基本属性之一是支持多任务,允许多个任务同时运行,但并不是真正的同时运行,而是宏 ...

  8. C#在代码中编写输出debug信息-类Debug的使用

    文章:C# 的两种debug 方法 文章:C#跟踪和调试程序-Debug类使用 很全面的文章,可以仔细学习使用下. 文章:C#调试类 没有仔细看. 关键字:Debug类和Trace类有什么区别? 微软 ...

  9. 2018 ICPC上海大都会赛重现赛 D Thinking-Bear magic (几何)

    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 D Thinking-Bear magic (几何) 链接:https://ac.nowcoder.com/acm/contest/163/ ...

  10. java之jvm

    1.JVM内存模型 线程独占:栈,本地方法栈,程序计数器线程共享:堆,方法区 回答以上问题是需回答两个要点:1. 各部分功能2. 是否是线程共享 2.JMM与内存可见性JMM是定义程序中变量的访问规则 ...