hadoop 自定义分组排序,求相同key中value最小值

本文介绍如何在Hadoop中使用自定义分组比较器实现数据分组,并通过Reducer计算每组内的最小值。主要涉及自定义分组比较器的实现及Reducer中的打擂算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在自定义排序上:http://blog.youkuaiyun.com/fln250/article/details/23731251,进行了分组,并实现最小值

首先,我们需要在配置完map,添加:job.setGroupingComparatorClass(MyGroupingComparator.class) //设置分组的java类;

MyGroupingComparator.class:

主要是将默认的两个比较方法进行重写,然后传到底层,根据返回的值,判断是否在一组,如果相同则在一组

MyReducer.class

通过打擂的算法,得出最小值打印

MyReducer

	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 {
			long min = Long.MAX_VALUE;
			for (LongWritable v2 : v2s) {
				if(v2.get()<min){
					min = v2.get();
				}
			}
			
			context.write(new LongWritable(k2.first), new LongWritable(min));
		};
	}
MyGroupingComparator

/**
		 * 分组的目的:例如:要在相同的key中,找出最小的值
		 * 把key相同的value放在一个集合----->即需要将key分组,但是NewK是对象,默认分组是比较里面的属性是否全部相同,全部相同就放在一组中,但是这样我们求最小值,有什么意义!
		 * 于是,我们只是比较对象中的某个值,如first
		 * @author Administrator
		 *
		 */
		static class MyGroupingComparator implements RawComparator<NewK>{
			/**
			 * 通过对象分组
			 */
			@Override
			public int compare(NewK o1, NewK o2) {
				// TODO Auto-generated method stub
				
				return (int)(o1.first-o2.first);
			}
			/**
			 * 通过对象的字节数组进行排序
			 */
			/**
			 * @param arg0 表示第一个参与比较的字节数组
			 * @param arg1 表示第一个参与比较的字节数组的起始位置
			 * @param arg2 表示第一个参与比较的字节数组的偏移量
			 * 
			 * @param arg3 表示第二个参与比较的字节数组
			 * @param arg4 表示第二个参与比较的字节数组的起始位置
			 * @param arg5 表示第二个参与比较的字节数组的偏移量
			 */
			@Override
			public int compare(byte[] arg0, int arg1, int arg2, byte[] arg3,
					int arg4, int arg5) {
				// TODO Auto-generated method stub
				/*
				 * 清楚我们的目的,是要比较NewK中的first,
				 * 1.first和second,first的字节在前
				 * 2.他们都是long,字节为8
				 * 3.起始为:0,数组偏移量:8,那么刚好可以比较出first
				 */
				return	WritableComparator.compareBytes(arg0, arg1,8, arg3, arg4,8);
			}
			
		}



好的,可以使用 MapReduce 框架来实现。 首先,需要编写 Mapper 类来读取大文件中的数据,将其输出为键值对。键为 NullWritable,值为 IntWritable,表示每一个数值。 ```java import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.mapreduce.Mapper; public class MaxMinMapper extends Mapper<Object, Text, NullWritable, IntWritable> { private IntWritable num = new IntWritable(); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); num.set(Integer.parseInt(line)); context.write(NullWritable.get(), num); } } ``` 然后,需要编写 Reducer 类来计算最大值和最小值。在 Reducer 类的 reduce() 方法中,将所有数值进行比较,并输出最大值和最小值。 ```java import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.mapreduce.Reducer; public class MaxMinReducer extends Reducer<NullWritable, IntWritable, NullWritable, IntWritable> { private IntWritable max = new IntWritable(Integer.MIN_VALUE); private IntWritable min = new IntWritable(Integer.MAX_VALUE); public void reduce(NullWritable key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { for (IntWritable val : values) { if (val.get() > max.get()) { max.set(val.get()); } if (val.get() < min.get()) { min.set(val.get()); } } context.write(NullWritable.get(), max); context.write(NullWritable.get(), min); } } ``` 最后,需要编写 Driver 类来设置 MapReduce 作业的输入、输出路径和使用的 Mapper、Reducer 类等信息。 ```java import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class MaxMinDriver { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "MaxMin"); job.setJarByClass(MaxMinDriver.class); job.setMapperClass(MaxMinMapper.class); job.setReducerClass(MaxMinReducer.class); job.setOutputKeyClass(NullWritable.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } } ``` 在命令行中运行程序: ```bash hadoop jar MaxMin.jar MaxMinDriver input output ``` 其中,MaxMin.jar 是打包后的程序包,input 是输入文件的路径,output 是输出结果的路径。 程序运行后,可以在输出路径下找到结果文件,其中记录了所有数值的最大值和最小值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值