3  3

3  2

3  1

2  2

2  1

1  1

-----------------期望输出

1  1

2  1

2  2

3  1

3  2

3  3

将以上数据进行排序,排序规则是:按照第一列升序排序,如果第一列数值相同,则按照第二列升序排序。

但是默认情况下结果是:

1  1

2  2

2  1

3  3

3  2

3  1

即默认情况下只有第一列参加排序,第二列并不参加,即原来的v2不能参与排序,想达到目标必须自定义类,该类必须将原来的k2和v2封装到一个类中,作为新的k2必须实现一个接口implements WritableComparable,于mapper  reducer平级,并对其中方法进行实现。这里自定义类NewK2如下:

static class NewK2 implements WritableComparable<NewK2>{
Long first;
Long second;
public NewK2(){}
public NewK2(long first, long second){
this.first = first;
this.second = second;
}
@Override
public void readFields(DataInput in) throws IOException {
this.first = in.readLong();
this.second = in.readLong();
}

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

/**
* 当k2进行排序时,会调用该方法.
* 当第一列不同时,升序;当第一列相同时,第二列升序
*/
@Override
public int compareTo(NewK2 o) {
final long minus = this.first - o.first;
if(minus !=0){
return (int)minus;
}
return (int)(this.second - o.second);
}
@Override
public int hashCode() {
return this.first.hashCode()+this.second.hashCode();
}

public boolean equals(Object obj){

if(!(obj instanceof NewK2))

return false;

NewK2 NK2=(NewK2)obj;

return (this.first==NK2.first&&this.second==NK2.second);

}
}

----------------

static class MyMapper extends Mapper<LongWritable, Text, NewK2, LongWritable>{
protected void map(LongWritable key, Text value, Context context) throws Exception {
final String[] splited = value.toString().split("\t");
final NewK2 k2 = new NewK2(Long.parseLong(splited[0]), Long.parseLong(splited[1]));
final LongWritable v2 = new LongWritable(Long.parseLong(splited[1]));
context.write(k2, v2);
};
}

static class MyReducer extends Reducer<NewK2, LongWritable, LongWritable, LongWritable>{
protected void reduce(NewK2 k2, java.lang.Iterable<LongWritable> v2s, Context context) throws Exception {
context.write(new LongWritable(k2.first), new LongWritable(k2.second));
};
}

---------------------------

package sort;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.net.URI; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner; public class SortApp {
static final String INPUT_PATH = "hdfs://mlj:9000/sort";
static final String OUT_PATH = "hdfs://mlj:9000/sort_out";
public static void main(String[] args) throws Exception{
final Configuration configuration = new Configuration(); final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), configuration);
if(fileSystem.exists(new Path(OUT_PATH))){
fileSystem.delete(new Path(OUT_PATH), true);
} final Job job = new Job(configuration, SortApp.class.getSimpleName()); //1.1 指定输入文件路径
FileInputFormat.setInputPaths(job, INPUT_PATH);
//指定哪个类用来格式化输入文件
job.setInputFormatClass(TextInputFormat.class); //1.2指定自定义的Mapper类
job.setMapperClass(MyMapper.class);
//指定输出<k2,v2>的类型
job.setMapOutputKeyClass(NewK2.class);
job.setMapOutputValueClass(LongWritable.class); //1.3 指定分区类
job.setPartitionerClass(HashPartitioner.class);
job.setNumReduceTasks(1); //1.4 TODO 排序、分区 //1.5 TODO (可选)合并 //2.2 指定自定义的reduce类
job.setReducerClass(MyReducer.class);
//指定输出<k3,v3>的类型
job.setOutputKeyClass(LongWritable.class);
job.setOutputValueClass(LongWritable.class); //2.3 指定输出到哪里
FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));
//设定输出文件的格式化类
job.setOutputFormatClass(TextOutputFormat.class); //把代码提交给JobTracker执行
job.waitForCompletion(true);
} static class MyMapper extends Mapper<LongWritable, Text, NewK2, LongWritable>{
protected void map(LongWritable key, Text value, org.apache.hadoop.mapreduce.Mapper<LongWritable,Text,NewK2,LongWritable>.Context context) throws java.io.IOException ,InterruptedException {
final String[] splited = value.toString().split("\t");
final NewK2 k2 = new NewK2(Long.parseLong(splited[0]), Long.parseLong(splited[1]));
final LongWritable v2 = new LongWritable(Long.parseLong(splited[1]));
context.write(k2, v2);
};
} static class MyReducer extends Reducer<NewK2, LongWritable, LongWritable, LongWritable>{
protected void reduce(NewK2 k2, java.lang.Iterable<LongWritable> v2s, org.apache.hadoop.mapreduce.Reducer<NewK2,LongWritable,LongWritable,LongWritable>.Context context) throws java.io.IOException ,InterruptedException {
context.write(new LongWritable(k2.first), new LongWritable(k2.second));
};
} /**
* 问:为什么实现该类?
* 答:因为原来的v2不能参与排序,把原来的k2和v2封装到一个类中,作为新的k2
*
*/
static class NewK2 implements WritableComparable<NewK2>{
Long first;
Long second; public NewK2(){} public NewK2(long first, long second){
this.first = first;
this.second = second;
} @Override
public void readFields(DataInput in) throws IOException {
this.first = in.readLong();
this.second = in.readLong();
} @Override
public void write(DataOutput out) throws IOException {
out.writeLong(first);
out.writeLong(second);
} /**
* 当k2进行排序时,会调用该方法.
* 当第一列不同时,升序;当第一列相同时,第二列升序
*/
@Override
public int compareTo(NewK2 o) {
final long minus = this.first - o.first;
if(minus !=0){
return (int)minus;
}
return (int)(this.second - o.second);
} @Override
public int hashCode() {
return this.first.hashCode()+this.second.hashCode();
} } }

  

mapreduce自定义排序(map端1.4步)的更多相关文章

  1. Hadoop mapreduce自定义排序WritableComparable

    本文发表于本人博客. 今天继续写练习题,上次对分区稍微理解了一下,那根据那个步骤分区.排序.分组.规约来的话,今天应该是要写个排序有关的例子了,那好现在就开始! 说到排序我们可以查看下hadoop源码 ...

  2. Hadoop学习之路(7)MapReduce自定义排序

    本文测试文本: tom 20 8000 nancy 22 8000 ketty 22 9000 stone 19 10000 green 19 11000 white 39 29000 socrate ...

  3. MapReduce自定义排序器不生效一个可能的原因

    有问题的代码: package com.mytq.weather; import org.apache.hadoop.io.WritableComparable; import org.apache. ...

  4. Hadoop mapreduce自定义分组RawComparator

    本文发表于本人博客. 今天接着上次[Hadoop mapreduce自定义排序WritableComparable]文章写,按照顺序那么这次应该是讲解自定义分组如何实现,关于操作顺序在这里不多说了,需 ...

  5. Hadoop on Mac with IntelliJ IDEA - 10 陆喜恒. Hadoop实战(第2版)6.4.1(Shuffle和排序)Map端 内容整理

    下午对着源码看陆喜恒. Hadoop实战(第2版)6.4.1  (Shuffle和排序)Map端,发现与Hadoop 1.2.1的源码有些出入.下面作个简单的记录,方便起见,引用自书本的语句都用斜体表 ...

  6. Hadoop2.4.1 MapReduce通过Map端shuffle(Combiner)完成数据去重

    package com.bank.service; import java.io.IOException; import org.apache.hadoop.conf.Configuration;im ...

  7. Hadoop基础-Map端链式编程之MapReduce统计TopN示例

    Hadoop基础-Map端链式编程之MapReduce统计TopN示例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.项目需求 对“temp.txt”中的数据进行分析,统计出各 ...

  8. MapReduce在Map端的Combiner和在Reduce端的Partitioner

    1.Map端的Combiner. 通过单词计数WordCountApp.java的例子,如何在Map端设置Combiner... 只附录部分代码: /** * 以文本 * hello you * he ...

  9. CCF CSP 201503-2 数字排序 (map+自定义排序)

    题目链接:http://118.190.20.162/view.page?gpid=T26 返回试题列表 问题描述 试题编号: 201503-2 试题名称: 数字排序 时间限制: 1.0s 内存限制: ...

随机推荐

  1. 50个Java多线程面试题(上)

    Java 语言一个重要的特点就是内置了对并发的支持,让 Java 大受企业和程序员的欢迎.大多数待遇丰厚的 Java 开发职位都要求开发者精通多线程技术并且有丰富的 Java 程序开发.调试.优化经验 ...

  2. Json安全

    1.不要使用顶级JSON数组,避免被<script>标签引用. 2.使用POST+密钥获取JSON,尽量不要用GET方式. 3.不要使用eval()将对象放入内存,eval()会执行所传入 ...

  3. CNN详解

    CNN详解 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7450413.html 前言 这篇博客主要就是卷积神经网络(CNN) ...

  4. KVM套件-linux基础

    KVM套件 使用KVM的虚拟机,通过KVM的虚拟机克隆功能,提高效率,避免在实验过程中重装系统. 另外,在LINUX系统上使用KVM的虚拟化,可以获得更好性能,且可以提前熟悉企业级虚拟化技术. 过程: ...

  5. 通过VM虚拟机安装Ubuntu server部署flask项目

    1. VM安装Ubuntu server 14.04,系统安装完成后,首先安装pip工具方便之后的包安装,此处需先使用 apt-get install update,apt-get install u ...

  6. boost::pool 库速记

    使用示例 #include <functional> #include <iostream> #include <boost/pool/pool.hpp> #inc ...

  7. Spring五个事务隔离级别和七个事务传播行为

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt216 Spring五个事务隔离级别和七个事务传播行为 1. 脏读 :脏读就是 ...

  8. ButterKnife的安装与使用以及ButterKnife右键不显示的大坑

    作为从安卓的的入门选手,第一次看到还以为是个第三方呢,从github下来之后感觉不对啊,这么多东西,后来一搜原来是个插件,而且不用从github上下载. 安装的方法很简单. 第一步:打开安卓studi ...

  9. 【C++小白成长撸】--(续)双偶数N阶魔阵

    原理: 把双偶数N阶魔阵均分为(N/4)^2个4阶魔阵(4*4) 每个魔阵的对角线都标为"-1",其余位置标为"0" 从第一个位置(a[0][0])从左到右,从 ...

  10. python 每日一练: 读取log文件中的数据,并画图表

    之前在excel里面分析log数据,简直日了*了. 现在用python在处理日志数据. 主要涉及 matplotlib,open和循环的使用. 日志内容大致如下 2016-10-21 21:07:59 ...