MapReduce按照两个字段对数据进行排序
按照k2排序,要求k2必须是可以比较的,即必须实现WritableComparable接口。
但是如果还想让别的字段(比如v2中的一些字段)参与排序怎么办?
需要重新定义k2....把需要参与排序的字段都放到k2中.
这块用代码实现:
假如数据现在的结构是
3 3
3 2
3 1
2 2
2 1
1 1
看代码:
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
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.output.FileOutputFormat; public class TwoIntSortApp { public static void main(String[] args) throws Exception {
Job job = Job.getInstance(new Configuration(), TwoIntSortApp.class.getSimpleName());
job.setJarByClass(TwoIntSortApp.class);
FileInputFormat.setInputPaths(job, args[0]); job.setMapperClass(TwoIntSortMapper.class);
job.setMapOutputKeyClass(TwoInt.class);
job.setMapOutputValueClass(NullWritable.class); job.setReducerClass(TwoIntSortReducer.class);
job.setOutputKeyClass(TwoInt.class);
job.setOutputValueClass(NullWritable.class); FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.waitForCompletion(true);
} public static class TwoIntSortMapper extends Mapper<LongWritable, Text, TwoInt, NullWritable>{
TwoInt k2 = new TwoInt();
@Override
protected void map(LongWritable key, Text value,
Mapper<LongWritable, Text, TwoInt, NullWritable>.Context context)
throws IOException, InterruptedException {
String[] splited = value.toString().split("\t");
k2.set(splited[0],splited[1]);
context.write(k2, NullWritable.get());
System.out.println("Mapper-----第一个数:"+k2.first+" 第二个数:"+k2.second);
}
} public static class TwoIntSortReducer extends Reducer<TwoInt, NullWritable, TwoInt, NullWritable>{
int i=1;
@Override
protected void reduce(TwoInt k2, Iterable<NullWritable> arg1,
Reducer<TwoInt, NullWritable, TwoInt, NullWritable>.Context context)
throws IOException, InterruptedException {
context.write(k2,NullWritable.get());
System.out.println("调用次数"+(i++));
System.out.println("Reducer-----第一个数:"+k2.first+" 第二个数:"+k2.second);
}
} public static class TwoInt implements WritableComparable<TwoInt>{
int first;
int second;
public void write(DataOutput out) throws IOException {
out.writeInt(first);
out.writeInt(second);
} public void set(String s1,String s2){
this.first = Integer.parseInt(s1);
this.second = Integer.parseInt(s2);
} public void readFields(DataInput in) throws IOException {
this.first = in.readInt();
this.second = in.readInt(); } public int compareTo(TwoInt o) {
int r1 = this.first - o.first;
if(r1 < 0){
return -1;
}else if(r1 > 0){
return 1;
}
int r2 = this.second - o.second;
return (r2 < 0 ? -1 : (r2 > 0 ? 1 : 0));
} @Override
public String toString() {
return this.first+"\t"+this.second;
}
}
}
//==============================================================
在job上设置Combiner类...
job.setCombinerClass(TwoIntSortReducer.class);//设置Combiner类
job.setGroupingComparatorClass(MyGroupingCompartor.class);//设置自定义的分组类
public static class MyGroupingCompartor extends WritableComparator{
@Override
public int compare(WritableComparable a, WritableComparable b) {
TwoInt aa = (TwoInt)a;
TwoInt bb = (TwoInt)b;
return aa.first-bb.first<0?-1:(aa.first-bb.first>0?1:0);//只要是第一列相同的就认为是一个分组.
/*
* 1 1
* 2 1
* 2 2
* 3 1
* 3 2
* 3 3
* 这样就分成了三组
*/
}
}
MapReduce按照两个字段对数据进行排序的更多相关文章
- mysql的if用法解决同一张数据表里面两个字段是否相等统计数据量。
MySQL的使用用法如下所示:格式:if(Condition,A,B)意义:当Condition为true时,返回A:当Condition为false时,返回B.作用:作为条件语句使用.mysql的i ...
- 连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识
(1)学习如何连接两个不同点云为一个点云,进行操作前要确保两个数据集中字段的类型相同和维度相等,同时了解如何连接两个不同点云的字段(例如颜色 法线)这种操作的强制约束条件是两个数据集中点的数目必须一样 ...
- sql server中如何将两个字段数据合并成一个字段显示(字段与字段添加特殊符号)
之前,我在做统计数据时,需要一个字段显示某月的订单数量和订单金额,要求组合成一个字段,用括号组合. 统计出来的结果大概是这样的,首先我们来创建一些模拟数据 ---创建订单表--- create tab ...
- mysql如何让两个字段数据都不能重复?
目录 场景 任务(需求) 行动(解决方案) 方案1:从代码层面解决(正确方案) 方案2:设置成两个唯一索引(正确方案) 方案3:删掉中间表,把从表的主键作为主表的外键,并将外键设置成唯一索引(正确方案 ...
- 一个表的两个字段具有相同的类型。如何仅用SQL语句交换这两列的数据?
--假设为A B两个字段--查询Select A As B, B As A From TableName --更新Update TableName Set A = B, B = A
- Python实现MapReduce,wordcount实例,MapReduce实现两表的Join
Python实现MapReduce 下面使用mapreduce模式实现了一个简单的统计日志中单词出现次数的程序: from functools import reduce from multiproc ...
- MapReduce实现两表的Join--原理及python和java代码实现
用Hive一句话搞定的,可是有时必需要用mapreduce 方法介绍 1. 概述 在传统数据库(如:MYSQL)中,JOIN操作是很常见且很耗时的.而在HADOOP中进行JOIN操作.相同常见且耗时, ...
- MySQL为数据表的指定字段插入数据
username not null 没有默认值/有默认值 insert不插入username字段 均不报错 2014年07月23日21:05 百科369 MySQL为数据表的指定字段插入数据 ...
- 选择两个字段时distinct位置的影响
当选择两个字段时,例如:"select XX1, XX2 from tb; ",那么将distinct放在前一个字段XX1之前和放在后一个字段XX2之前,结果有什么不同呢? 先说结 ...
随机推荐
- 第三百零三天 how can I 坚持
今天年会,运气还不错,竟然中了个小奖,一个榨汁机,已经很满足了. 今天加上了她,感觉挺合适,就怕一句话聊不来就带搭不理的了.她很好,懂得知足,不攀比. 弟弟今天把房子首付交了,把贷款办完就算安心了,目 ...
- 【转】深受开发者喜爱的10大Core Data工具和开源库
http://www.cocoachina.com/ios/20150902/13304.html 在iOS和OSX应用程序中存储和查询数据,Core Data是一个很好的选择.它不仅可以减少内存使用 ...
- Codeforces 599D Spongebob and Squares(数学)
D. Spongebob and Squares Spongebob is already tired trying to reason his weird actions and calculati ...
- jquery easyui添加图标扩展
easyui中有很多通过iconCls="icon-reload"这样的属性引入小图标显示,当然我们也可以自己添加自己的小图标. 方式:1.我们可以在jquery easyui的文 ...
- 论DATASNAP中间件对象池
在此,笔者以DATASNAP为例,其它中间件以此类推. 中间件为什么要使用对象池? 对象池——让所有的对象免堕轮回之苦,对象不再为其生和死而烦恼. 要想让中间件长久稳定地运行,做到无人值守,对象池很重 ...
- HDU/杭电2013多校第三场解题报告
今天悲剧了,各种被虐啊,还是太年轻了 Crime 这道题目给的时间好长,第一次就想到了暴力,结果华丽丽的TLE了. 后来找了一下,发现前24个是1, 2, 6, 12, 72, 72, 864, 17 ...
- freemaker自定义分页控件实现
<link href="${res}/css/pages-jhdb.css" rel="stylesheet" type="text/css&q ...
- 代码静态分析工具——splint的学习与使用
引言 最近在项目中使用了静态程序分析工具PC-Lint,体会到它在项目实施中带给开发人员的方便.PC-Lint是一款针对C/C++语言.windows平台的静态分析工具,FlexeLint是针对其他平 ...
- 简单http笔记
https是以安全为目的的网络传输协议,可以认为是http的安全版,https使用ssl协议保证安全传输.https位于网络模型的应用层,使用默认端口443进行通信,URL以https开头是https ...
- AngularJS应用的解析
模板(Templates) 模板是您用HTML和CSS编写的文件,展现应用的视图. 您可给HTML添加新的元素.属性标记,作为AngularJS编译器的指令. AngularJS编译器是完全可扩展的, ...