Mapreduce 求每个学科的平均分,学科作为行键,成绩作为列族,如何创建一个数组遍历成绩。要求用读入的Hbase数据
时间: 2024-02-27 22:55:32 浏览: 57
求学生平均成绩MapReduce实例
在 MapReduce 中读取 HBase 数据通常需要使用 HBase 提供的 InputFormat,例如 `TableInputFormat`。`TableInputFormat` 输出的键值对的键是 `ImmutableBytesWritable` 类型,表示行键;值是 `Result` 类型,表示一个 HBase 行。
下面是一个简单的示例代码,假设 HBase 中的表名为 `scores`,有一个列族 `cf`,列名为 `score`,存储学科成绩。我们需要计算每个学科的平均分,学科作为键,成绩作为列族。
```java
public static class AvgScoreMapper extends TableMapper<Text, IntWritable> {
private Text subject = new Text();
private IntWritable score = new IntWritable();
@Override
public void map(ImmutableBytesWritable rowKey, Result result, Context context) throws IOException, InterruptedException {
String subjectStr = new String(rowKey.get());
subject.set(subjectStr);
byte[] scoreBytes = result.getValue(Bytes.toBytes("cf"), Bytes.toBytes("score"));
int scoreInt = Bytes.toInt(scoreBytes);
score.set(scoreInt);
context.write(subject, score);
}
}
public static class AvgScoreReducer extends Reducer<Text, IntWritable, Text, DoubleWritable> {
private DoubleWritable avgScore = new DoubleWritable();
@Override
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
int count = 0;
for (IntWritable value : values) {
sum += value.get();
count++;
}
double avg = (double) sum / count;
avgScore.set(avg);
context.write(key, avgScore);
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "AvgScore");
job.setJarByClass(AvgScore.class);
Scan scan = new Scan();
scan.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("score"));
TableMapReduceUtil.initTableMapperJob("scores", scan, AvgScoreMapper.class, Text.class, IntWritable.class, job);
job.setReducerClass(AvgScoreReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(DoubleWritable.class);
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
```
在 Mapper 中,我们首先将行键转换成字符串,作为学科;然后从 `Result` 中取出 `cf:score` 列的值,将其转换成整数类型,作为成绩。最后将学科和成绩分别设置到 `Text` 和 `IntWritable` 对象中,并输出键值对。
在 Reducer 中,我们首先对相同学科的所有成绩进行累加,并记录成绩的个数。然后计算平均值,将学科和平均值分别设置到 `Text` 和 `DoubleWritable` 对象中,并输出键值对。
在主程序中,我们首先创建一个 `Scan` 对象,指定要读取的列族和列名。然后使用 `TableMapReduceUtil` 类的 `initTableMapperJob` 方法设置输入格式、Mapper 类、输出键值对类型等信息。最后设置 Reducer 类、输出键值对类型等信息,并提交作业。
在以上示例代码中,我们并没有使用数组来遍历成绩。在 MapReduce 中,我们通常使用迭代器来遍历值的集合。在 Reducer 中,输入的值是一个 `Iterable` 对象,可以使用 `for` 循环遍历所有的成绩。在示例代码中,我们使用增强型 `for` 循环来遍历值的集合。
阅读全文