这个是最近的一个实验,其中这个实验老师的要求是
1 统计每个班成绩的最大值 最小值 并且输出姓名 如果有多个那么要都要输出 ,然后输出每个班的平均值 再者就是每个班的成绩分布,优秀良好,及格不及格的个数
2 统计全部成绩的最大值最小值 要求如上
其中有一些思路可以说一下,一开始我是准备创建一个对象数组来存储每个班级的 最大值 最小值 姓名 还有总和 个数 但是这样很麻烦,因为要初始化,还有班级的个数,这一些都要处理 所以最后直接用变量来统计, 其中map就很简单了,就是把班级作为key value的属性是 班级 姓名 还有成绩,在reduce下 这是总共学生属性的变量还有班级学生的属性,这里可以看代码,初始化的位置不同,就是在每次处理完一个班级后,更新总共的属性 然后输出该班级的结果 当班级到达总共的时候输出总共的属性就可以,剩下的就是一些if else 判断也没有什么
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
public class classsorce {
public static class getmap extends Mapper<Object,Text,Text,Text> {
public void map(Object key,Text value,Context context)throws IOException,InterruptedException {
String[] line = value.toString().split("\\s+");
String class_id = line[0];
String name_id = line[1];
String grade_id = line[2];
String class_key = class_id.substring(8,10);
context.write(new Text(class_key),new Text(class_id+" "+name_id+" "+grade_id));
}
}
public static class getreduce extends Reducer<Text,Text,Text,Text> {
int cnt = 0;
int total_max = 0;
int total_min = 100;
String total_max_name;
String total_min_name;
int[] total_allocation = {0,0,0,0,0};
int total_sum = 0;
int total_student = 0;
public void reduce(Text key,Iterable<Text> value,Context context) throws IOException,InterruptedException {
int[] grade_allocation = {0,0,0,0,0};
int grade_max = 0;
int grade_min = 100;
int grade_sum = 0;
int number_student = 0;
String grade_name_max = "";
String grade_name_min = "";
String[] grade_description = {"优秀", "良好", "中等", "及格", "不及格"};
String class_name= "";
String space = " ";
for(Text lines : value) {
String[] line = lines.toString().split("\\s+");
if(line.length == 3) {
String id = line[0];
String grade = line[2];
String name1 = line[1];
class_name = id;
int grade1 = Integer.parseInt(grade);
grade_sum += grade1;
number_student++;
// 计算成绩等级
int tmp = grade1/10;
if(tmp <= 5) {
grade_allocation[0]+=1;
}
else if(tmp >= 6){
if(tmp == 10)
tmp = tmp-6;
else
tmp = tmp - 5;
grade_allocation[tmp] = grade_allocation[tmp]+1;
}
//更新最大值 以及姓名
if(grade1 > grade_max) {
grade_max = grade1;
grade_name_max = name1 +" ";
}
else if(grade1 == grade_max) {
grade_name_max += name1+ " ";
}
//更新最小值以及姓名
if(grade1 < grade_min) {
grade_min = grade1;
grade_name_min = name1 + " ";
}
else if(grade1 == grade_min) {
grade_name_min += name1 + " ";
}
}
}
//更新全部学生的属性
total_student+= number_student;
total_sum += grade_sum;
cnt++;
//更新最大值最小值
if(grade_max > total_max) {
total_max = grade_max;
total_max_name = grade_name_max + " " + class_name.substring(8,10) + " ";
}
else if(grade_max == total_max) {
total_max_name += grade_name_max + " " + class_name.substring(8,10) + " ";
}
if(grade_min < total_min) {
total_min = grade_min;
total_min_name = grade_name_min + " " + class_name.substring(8,10) + " ";
}
else if(grade_min == total_min) {
total_min_name += grade_name_min +" " + class_name.substring(8,10) + " ";
}
for(int i = 0;i < 5;i++){
total_allocation[i] += grade_allocation[i];
}
//写入一个班的成绩统计
context.write(new Text("class : " + class_name.substring(8,10)),new Text("average : " + Double.toString(grade_sum*1.0/number_student)));
String[] put_max = grade_name_max.split("\\s+");
String[] put_min = grade_name_min.split("\\s+");
for(int i = 0;i < put_max.length;i++){
context.write(new Text(space),new Text("max_grade : " + put_max[i] + " " + Integer.toString(grade_max)));
}
for(int i = 0;i < put_min.length;i++){
context.write(new Text(space),new Text("min_grade : " + put_min[i] + " "+ Integer.toString(grade_min)));
}
for(int i = 0;i < 5;i++){
context.write(new Text(space + grade_description[i] + " : "),new Text(Integer.toString(grade_allocation[i])));
}
//写入全部班级的成绩统计
if(cnt == 10){
context.write(new Text("average : " ) ,new Text(Double.toString(total_sum*1.0/total_student)));
String[] puttotalmax = total_max_name.split("\\s+");
String[] puttotalmin = total_min_name.split("\\s+");
context.write(new Text(space+ "totalmax_grade : ") ,new Text(Integer.toString(total_max)));
for(int i = 0;i < puttotalmax.length;i+=2) {
context.write(new Text(space),new Text( " " + puttotalmax[i] + " " +puttotalmax[i+1]));
//i+=2;
}
context.write(new Text(space+ "totalmin_grade : ") ,new Text(Integer.toString(total_min)));
for(int i = 0;i < puttotalmin.length;i+=2) {
context.write(new Text(space),new Text( "" + puttotalmin[i] + " " + puttotalmin[i+1]));
//i+=2;
}
for(int i = 0;i < 5;i++) {
context.write(new Text(space + grade_description[i] + " : " ),new Text(Integer.toString(total_allocation[i])));
}
}
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf,"classscore");
job.setJarByClass(classsorce.class);
job.setMapperClass(getmap.class);
job.setReducerClass(getreduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job,new Path("hdfs://192.168.200.132:9000/home/fym/input2"));
FileOutputFormat.setOutputPath(job,new Path("hdfs://192.168.200.132:9000/home/fym/output2"));//(job,new Path(otherArgs[1]));
System.exit(job.waitForCompletion(true)?0:1);
System.out.println("end");
}
}