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之前,结果有什么不同呢? 先说结 ...
随机推荐
- IIS中使用PUT方法錯誤記錄
在IIS7.5中使用PUT,DELETE方法時會遇到404,405錯誤,特記錄解決辦法:404: 405: 在web.config的system.webServer節點中加入 <modules ...
- HTML5每日一练之input新增加的六种时间类型应用
今天介绍一下input在HTML5中新增加的时间类型的应用,与昨天的练习一样,如果在以下这几种输入框中输入的格式不正确,也是无法提交的. 注意:此种类型的input在Opera10+中效果为佳,Chr ...
- Tomcat中配置JNDI数据源
准备工作: Tomcat版本:tomcat6.0以上 下例中均使用MySQL数据库 将对应数据源的jar包和MySQL的驱动包拷贝至tomcat的lib文件夹下 一.全局数据源 1步骤一:配置 在to ...
- JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法
JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 * 可以由Connection得到 */ 具体的应用代码: @Te ...
- Spring MVC SimpleUrlHandlerMapping example
In Spring MVC application, the SimpleUrlHandlerMapping is the most flexible handler mapping class, w ...
- eclipse中的js文件报错的解决办法
在使用别人的项目的时候,导入到eclipse中发现js文件报错,解决办法是关闭eclipse的js校验功能. 三个步骤: 1. 右键点击项目->properties->Validation ...
- win8 或 win2008 系统 TFS 打开或获取源代码非常慢
最近刚更新了win8.1 .打开VS2012后,准备签出个文件,突然发现速度非常慢.打开个TFS目录都要过10多秒才能看到所有子内容.一开始以为是VS的问题更新了U4补丁.结果还是一样.后来googl ...
- [刷题codeforces]651B/651A
651B Beautiful Paintings 651A Joysticks 点击可查看原题 651B是一个排序题,只不过多了一步去重然后记录个数.每次筛一层,直到全为0.从这个题里学到一个正确姿势 ...
- mount nfs的可选参数
mount nfs的可选参数:HARD mount和SOFT MOUNT:HARD:NFS CLIENT会不断的尝试与SERVER的连接(在后台,不会给出任何提示信息,在LINUX下有的版本仍然会给出 ...
- C# 钩子HOOK专题(1)
目录 基本概念 运行机制 钩子类型 作者 基本概念 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程 ...