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之前,结果有什么不同呢? 先说结 ...
随机推荐
- HDU 5776 sum (模拟)
sum 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5776 Description Given a sequence, you're asked ...
- HDU1874畅通工程续(floyd||dijkstra)
看了看floyd和dijkstra,然后就找了两个练习来捉 #include<iostream> #include<stdio.h> #include<string.h& ...
- JavaScript随笔记(一)基础概念以及变量类型
一.JavaScript中的基础概念 1.defer属性 一般我们在引用外部js文件的时候往往是将引用文件的位置放在标签当中,比如那么在标签中引入多个js文件时,浏览器会按照引入顺序加载执行这些引入的 ...
- Unity3D之Mecanim动画系统学习笔记(一):认识Mecanim动画系统
Mecanim简介 Mecanim动画系统是Unity3D4.0开始引入的一套全新的动画系统,主要提供了下面4个方面的功能: 针对人形角色提供一套特殊的工作流. 动画重定向的能力,可以非常方便的把动画 ...
- 【Java】IO技术的使用——用IO实现大文件的复制
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827481.html 用IO进行文件复制,实质就是用FileInputStream链接要复制的文件,按一定规模 ...
- Nexus搭建Manven
Nexus相当于中转服务器,减轻网络的负载,加速项目搭建的进程 1.下载地址:http://www.sonatype.org/nexus/go 2.下载的是zip包,解压后进入D:\nexus-2.8 ...
- rxjava各种使用场景
1. 数据的三级缓存 final Observable memory = Observable.create(new Observable.OnSubscribe() { @Override publ ...
- 通过yum安装Nagios
通过yum安装Nagios 2012年04月05日 ⁄ Nagios ⁄ 暂无评论 QQ空间新浪微博腾讯微博人人网更多3 前提先自行安装好Apache+php 测试环境主监控机:CentOS ...
- 网络编程中常见地址结构与转换(IPv4/IPv6)
1. sockaddr/sockaddr_in/in_addr (IPv4).sockaddr6_in/in6_addr/addrinfo (IPv6) struct sockaddr { unsig ...
- C#实现对Word文件读写[转]
手头上的一个项目报表相对比较简单,所以报表打印采用VBA引擎,通过定制Word模版,然后根据模版需要填充数据,然后OK,打印即可. 实现方法:首先需要引用VBA组建,我用的是Office2003 Pr ...