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之前,结果有什么不同呢? 先说结 ...
随机推荐
- ES6学习小计
1.增加了for of语法,对应C#里的foreach,注意ES5中的 for in只会传递0,1,2.....序号,并且是字符for-of循环语句通过方法调用来遍历各种集合.数组.Maps对象.Se ...
- 利用hashtable和time函数加速Lisp程序
程序功能是从一个英文文本中得到单词表,再得到押韵词表.即输出可能这样开始: a ameoeba alba samba marimba... 这样结束: ...megahertz gigahertz j ...
- oracle 11g 之 result cache
oracle 11g 之 result cache 今天是2013-10-12,打算最近时间研究一下shared pool的相关原理以及awr报告分析.今天学习一下在oracle 11g shared ...
- Hadoop 2.0+YARN启动脚本分析与实战经验
start-all.sh脚本现在已经废弃,推荐使用start-dfs.sh和start-yarn.sh分别启动HDFS和YARN. 在新一代的Hadoop里面HDFS称为了统一存储的平台,而YARN成 ...
- Eclipse添加小工具_打开当前文件所在文件夹
CopyRight yuhuashi http://www.cnblogs.com/chuyuhuashi/archive/2012/05/06/2485831.html 默认情况下使用eclip ...
- DuiLib(三)——控件消息
上一篇讲了控件创建,这篇说说控件消息.directui的中心思想是在真实窗口之上画出所有控件,那这些控件是如何获取各自消息的? 通过第一篇的示例可以看到窗口消息的传递过程: CWindowWnd::_ ...
- C++,C#,Python
1.C++的思路:无论是基本类型,还是类类型,对象的传递提供了两种方式,一个是整体拷贝,一个是复制引用.整体拷贝对应着copy构造和copy赋值,复制引用就是通过引用或者指针实现的,当然指针本身还是整 ...
- 从零开始学android开发-View的setOnClickListener的添加方法
1)第一种,也是最长见的添加方法(一下都以Button为例) Button btn = (Button) findViewById(R.id.myButton); btn .setOnClickLis ...
- linux下tomcat开机自启动
tomcat自启动配置: 方法一: vi /etc/rc.local 添加如下一行 /opt/apache-tomcat-7.0.29/bin/startup.sh (脚本绝对路径) 注意:要添加在e ...
- hive 经常使用命令
1.查看表结构信息 desc formatted table_name; desc table_name; 查看关联文件: desc extended f_tblog_online_mds; ...