【细节拉满】Hadoop课程设计项目,使用idea编写基于MapReduce的学生成绩分析系统(附带源码、项目文件下载地址)
目錄
1 數(shù)據(jù)源(學(xué)生成績.csv)
2 hadoop平臺上傳數(shù)據(jù)源
3 idea代碼
3.1 工程框架
3.2 導(dǎo)入依賴
3.4 六個mapreduce
3.4.1?計算每門成績的最高分、最低分、平均分(Mma)
3.4.2?計算每個學(xué)生的總分及平均成績并進(jìn)行排序(Sas)
3.4.3?統(tǒng)計所有學(xué)生的信息(Si)
3.4.4?統(tǒng)計每門課程中相同分?jǐn)?shù)分布情況(Css)
3.4.5?統(tǒng)計各性別的人數(shù)及他們的姓名(Snn)
3.4.6?統(tǒng)計每門課程信息(Ci)
4 運(yùn)行
5 改進(jìn)
? ? ? ? ?本文只是用來分享代碼,如果想要學(xué)習(xí)MapReduce如何去寫的請轉(zhuǎn)至下面的參考博客,該篇博客以“”統(tǒng)計每門課程中相同分?jǐn)?shù)分布情況”為模板,從問題分析入手,一步步創(chuàng)建一個mapper、reducer和main(driver)從而組成一整個的MapReduce。
【手把手 腦把腦】教會你使用idea基于MapReduce的統(tǒng)計數(shù)據(jù)分析(從問題分析到代碼編寫)_扎哇太棗糕的博客-CSDN博客
不想跟著博客一步步操作的也可以選擇直接下載項目文件,并在自己的idea上運(yùn)行,數(shù)據(jù)源依舊是以下的學(xué)生成績。
Hadoop-MapReduce項目代碼ZIP壓縮包+面向小白(注釋詳細(xì)清晰)-Hadoop文檔類資源-CSDN下載
1 數(shù)據(jù)源(學(xué)生成績.csv)
💥 舊坑勿踩:可以復(fù)制下面數(shù)據(jù),粘貼到txt里把文件拓展格式改為csv,在上傳至Hadoop平臺之前一定要確保文件的編碼方式為utf-8(否則中文會亂碼),具體操作為使用記事本打開學(xué)生成績.csv文件,看右下角的編碼方式,如果不是utf-8則可以將文件另存為時修改其編碼方式。
💥一定一定一定不要為了元數(shù)據(jù)的好看就在第一行為數(shù)據(jù)加字段名,看是好看了,到時候運(yùn)行不出來結(jié)果就很難受,不要問我怎么知道的,一個下午的血淋淋的教訓(xùn)。
英語,李沐,85,男,20 數(shù)學(xué),李沐,54,男,20 音樂,李沐,54,男,20 體育,李沐,34,男,20 語文,李媛,81,女,20 音樂,李媛,85,女,20 體育,李媛,89,女,20 語文,馬珂,75,女,19 英語,馬珂,85,女,19 音樂,馬珂,75,女,19 體育,馬珂,65,女,19 語文,潘琴,42,女,20 英語,潘琴,48,女,20 音樂,潘琴,48,女,20 體育,潘琴,78,女,20 英語,秦燦,75,男,19 數(shù)學(xué),秦燦,89,男,19 音樂,秦燦,85,男,19 體育,秦燦,99,男,19 語文,王靚,85,女,21 英語,王靚,85,女,21 數(shù)學(xué),王靚,48,女,21 音樂,王靚,86,女,21 音樂,王靚,85,女,21 體育,王靚,96,女,21 體育,王靚,87,女,21 英語,吳起,85,男,20 數(shù)學(xué),吳起,85,男,20 英語,張翔,96,男,20 數(shù)學(xué),張翔,85,男,20 音樂,張翔,85,男,20 體育,張翔,87,男,20 語文,鄭虎,85,男,20 數(shù)學(xué),鄭虎,85,男,20 音樂,鄭虎,88,男,20 體育,鄭虎,68,男,20 語文,周偉,76,男,19 英語,周偉,85,男,19 數(shù)學(xué),周偉,76,男,19 音樂,周偉,99,男,19 體育,周偉,90,男,19 數(shù)學(xué),朱鴻,90,男,21 音樂,朱鴻,80,男,21 體育,朱鴻,81,男,212 hadoop平臺上傳數(shù)據(jù)源
????????Hadoop平臺上傳數(shù)據(jù),其實(shí)也可以理解為向HDFS里存儲數(shù)據(jù),前提是Hadoop的集群必須搭建好,這里就默認(rèn)大家都已經(jīng)搭建完成并可以正常運(yùn)行。這里可以如下圖雙擊hadoop下的sbin目錄下的start-all.cmd啟動集群。
????????集群啟動成功后,在源數(shù)據(jù)的存儲路徑下打開DOS窗口,可以在該目錄的文件路徑框下輸入cmd打開,或者直接在桌面打開DOS窗口再cd進(jìn)源數(shù)據(jù)的存儲路徑。按照下圖使用命令創(chuàng)建目錄并將源數(shù)據(jù)(學(xué)生成績.csv)上傳至hadoop平臺
3 idea代碼
3.1 工程框架
新建一個maven工程,建立如下工程框架 :
3.2 導(dǎo)入依賴
????????MapReduce需要四個核心依賴,hadoop-client、hadoop-hdfs、hadoop-common、hadoop-mapreduce-client-core,依賴復(fù)制粘貼進(jìn)自己的項目一定要記得刷新依賴,避免依賴還沒導(dǎo)入成功就運(yùn)行導(dǎo)致報錯。
<dependencies><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>2.7.3</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>2.7.3</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>2.7.3</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-mapreduce-client-core</artifactId><version>2.7.3</version></dependency> </dependencies>3.3 系統(tǒng)主入口(menu)
//這里的導(dǎo)包是完成跨package調(diào)用其它包里的類 import couerse_info.CiMain; import course_score_same.CssMain; import max_min_avg.MmaMain; import sex_number_name.SnnMain; import student_info.SiMain; import sum_avg_sort.SasMain;import java.lang.reflect.Method; import java.util.Scanner;public class menu {public static void main(String[] args) {try {Scanner scanner = new Scanner(System.in);while(true){System.out.println("=========基于MapReduce的學(xué)生成績分析=========");System.out.println("1、計算每門成績的最高分、最低分、平均分");System.out.println("2、計算每個學(xué)生的總分及平均成績并進(jìn)行排序");System.out.println("3、統(tǒng)計所有學(xué)生的信息");System.out.println("4、統(tǒng)計每門課程中相同分?jǐn)?shù)分布情況");System.out.println("5、統(tǒng)計各性別的人數(shù)及他們的姓名");System.out.println("6、統(tǒng)計每門課程信息");System.out.println("7、退出");System.out.print("請輸入你想要選擇的功能:");int option = scanner.nextInt();Method method = null;switch(option){case 1:method = MmaMain.class.getMethod("main", String[].class);method.invoke(null, (Object) new String[] {});break;case 2:method = SasMain.class.getMethod("main", String[].class);method.invoke(null, (Object) new String[] {});break;case 3:method = SiMain.class.getMethod("main", String[].class);method.invoke(null, (Object) new String[] {});break;case 4:method = CssMain.class.getMethod("main", String[].class);method.invoke(null, (Object) new String[] {});break;case 5:method = SnnMain.class.getMethod("main", String[].class);method.invoke(null, (Object) new String[] {});break;case 6:method = CiMain.class.getMethod("main", String[].class);method.invoke(null, (Object) new String[] {});break;case 7:System.exit(1);break;default:System.out.println("輸入正確的功能按鍵!!");break;}}} catch (Exception e) {e.printStackTrace();}} }3.4 六個mapreduce
3.4.1?計算每門成績的最高分、最低分、平均分(Mma)
package max_min_avg;import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException; /* stu[0]:課程名稱 stu[1]:學(xué)生姓名 stu[2]:成績 stu[3]:性別 stu[4]:年齡 該功能實(shí)現(xiàn)的計算出每門課程中的最高分、最低分、平均分*/public class MmaMapper extends Mapper<LongWritable,Text,Text,Text> {@Overrideprotected void map(LongWritable key1,Text value1,Context context)throws IOException,InterruptedException{//將文件的每一行傳遞過來,使用split分割后利用字符數(shù)組進(jìn)行接收String[] splits = value1.toString().split(",");//向Reducer傳遞參數(shù)-> Key:課程 Value:成績context.write(new Text(splits[0]),new Text(splits[2]));} } package max_min_avg;import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List;public class MmaReducer extends Reducer<Text, Text,Text, Text> {@Overrideprotected void reduce(Text key,Iterable<Text> value,Context context)throws IOException,InterruptedException{//Arraylist集合儲存所有的成績數(shù)據(jù),借用collections的方法求最大值最小值List<Integer> list = new ArrayList<>();for(Text v: value){list.add(Integer.valueOf(v.toString()));}//求max及minint maxScore = Collections.max(list);int minScore = Collections.min(list);// 求平均成績int sum = 0;for(int score: list){sum += score;}double avg = sum / list.size();System.out.println("*****************************************");String result = "的最高分:"+maxScore+" 最低分:"+minScore+" 平均分:"+avg;System.out.println(key.toString()+result);context.write(key,new Text(result));} } package max_min_avg;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import java.io.IOException; import java.net.URI; import java.net.URISyntaxException;public class MmaMain {public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException, URISyntaxException {//創(chuàng)建job和“統(tǒng)計相同課程相同分?jǐn)?shù)的人數(shù)”任務(wù)入口Configuration conf = new Configuration();Job job = Job.getInstance(conf);job.setJarByClass(MmaMain.class);//設(shè)置Mapper和Reducer的入口job.setMapperClass(MmaMapper.class);job.setReducerClass(MmaReducer.class);//設(shè)置Mapper的輸入輸出類型job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(Text.class);//設(shè)置Reducer的輸入輸出類型job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);//指定輸入輸出路徑String inputPath = "hdfs://localhost:9000/mapreduce/input/學(xué)生成績.csv";String outputPath = "hdfs://localhost:9000/mapreduce/output/最大值最小值平均值.txt";FileInputFormat.setInputPaths(job,new Path(inputPath));FileOutputFormat.setOutputPath(job,new Path(outputPath));//輸出路徑存在的話就刪除,不然就只能手動刪除,否則會報該文件已存在的異常FileSystem fileSystem = FileSystem.get(new URI(outputPath), conf);if (fileSystem.exists(new Path(outputPath))) {fileSystem.delete(new Path(outputPath), true);}//執(zhí)行jobjob.waitForCompletion(true);} }3.4.2?計算每個學(xué)生的總分及平均成績并進(jìn)行排序(Sas)
package sum_avg_sort;import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException;/* stu[0]:課程名稱 stu[1]:學(xué)生姓名 stu[2]:成績 stu[3]:性別 stu[4]:年齡 該功能實(shí)現(xiàn):統(tǒng)計每個學(xué)生總分平均分并對成績進(jìn)行排序*/ public class SasMapper extends Mapper<LongWritable, Text,Text,Text> {@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {//將文件的每一行傳遞過來,使用split分割后利用字符數(shù)組進(jìn)行接收String[] stu = value.toString().split(",");//向Reducer傳遞參數(shù)-> Key:學(xué)生姓名 Value:成績context.write(new Text(stu[1]),new Text(stu[2]));} } package sum_avg_sort;import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List;public class SasReducer extends Reducer<Text,Text,Text,Text> {@Overrideprotected void reduce(Text key, Iterable<Text> values,Context context) throws IOException, InterruptedException {System.out.println("*********************************************************************");//定義一個ArrayList集合接收該學(xué)生的各項成績List<Integer> scores = new ArrayList<>();for(Text value:values){scores.add(Integer.valueOf(value.toString()));}//對該學(xué)生的成績進(jìn)行求總分、平均分int num = 0, sum = 0;for(Integer score:scores){sum = sum + score.intValue();num = num + 1;}float avg = sum / num;//成績排序Collections.sort(scores);//使用一個字符串拼接排好序的所有成績String sort = "的總分:"+sum+" 平均分:"+avg+" 該生的成績從低到高排序是:";for(Integer score:scores){sort = sort + score + " ";}System.out.println(key.toString()+sort);//輸出context.write(key,new Text(sort));} } package sum_avg_sort;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import java.io.IOException; import java.net.URI; import java.net.URISyntaxException;public class SasMain {public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException, URISyntaxException {//創(chuàng)建一個job和任務(wù)的入口Configuration conf = new Configuration();Job job = Job.getInstance(conf);job.setJarByClass(SasMain.class);//設(shè)置mapper和reducer的入口job.setMapperClass(SasMapper.class);job.setReducerClass(SasReducer.class);//設(shè)置mapper輸出類型job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(Text.class);//設(shè)置reducer的輸出類型job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);//指定輸入輸出路徑String inputPath = "hdfs://localhost:9000/mapreduce/input/學(xué)生成績.csv";String outputPath = "hdfs://localhost:9000/mapreduce/output/每個學(xué)生總分平均分排序.txt";FileInputFormat.setInputPaths(job,new Path(inputPath));FileOutputFormat.setOutputPath(job,new Path(outputPath));//輸出路徑存在的話就刪除,不然就只能手動刪除,否則會報該文件已存在的異常FileSystem fileSystem = FileSystem.get(new URI(outputPath), conf);if (fileSystem.exists(new Path(outputPath))) {fileSystem.delete(new Path(outputPath), true);}//執(zhí)行jobjob.waitForCompletion(true);} }3.4.3?統(tǒng)計所有學(xué)生的信息(Si)
package student_info;import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException; /* stu[0]:課程名稱 stu[1]:學(xué)生姓名 stu[2]:成績 stu[3]:性別 stu[4]:年齡 該功能實(shí)現(xiàn):統(tǒng)計所有學(xué)生課程考試信息*/ public class SiMapper extends Mapper<LongWritable,Text,Text,Text> {@Overrideprotected void map(LongWritable Key1, Text value1,Context context) throws IOException, InterruptedException {//將文件的每一行傳遞過來,使用split分割后利用字符數(shù)組進(jìn)行接收String[] splits= value1.toString().split(",");//拼接姓名+性別+年齡String name = splits[1];String sex = splits[3];String age = splits[4];String stu_info = name+"-"+sex+"-"+age;//拼接課程+成績String course = splits[0];String score = splits[2];String course_info = course+"-"+score;//向Reducer傳遞參數(shù)-> Key:姓名+性別+年齡 Value:課程+成績context.write(new Text(stu_info),new Text(course_info));} } package student_info;import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException; import java.util.ArrayList; import java.util.List;public class SiReducer extends Reducer<Text, Text,Text, Text> {@Overrideprotected void reduce(Text key,Iterable<Text> values,Context context)throws IOException,InterruptedException{//拼接學(xué)生各科考試成績信息String scoreInfo = "";for(Text value:values){scoreInfo = scoreInfo + value+" ";}System.out.println("********************************************************");System.out.println(key.toString()+"\n"+scoreInfo);context.write(key,new Text(scoreInfo));} } package student_info;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import java.io.IOException; import java.net.URI; import java.net.URISyntaxException;public class SiMain {public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException, URISyntaxException {//創(chuàng)建job和“統(tǒng)計相同課程相同分?jǐn)?shù)的人數(shù)”任務(wù)入口Configuration conf = new Configuration();Job job = Job.getInstance(conf);job.setJarByClass(SiMain.class);//設(shè)置Mapper和Reducer的入口job.setMapperClass(SiMapper.class);job.setReducerClass(SiReducer.class);//設(shè)置Mapper的輸入輸出類型job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(Text.class);//設(shè)置Reducer的輸入輸出類型job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);//指定輸入輸出路徑String inputPath = "hdfs://localhost:9000/mapreduce/input/學(xué)生成績.csv";String outputPath = "hdfs://localhost:9000/mapreduce/output/學(xué)生信息.txt";FileInputFormat.setInputPaths(job,new Path(inputPath));FileOutputFormat.setOutputPath(job,new Path(outputPath));//輸出路徑存在的話就刪除,不然就只能手動刪除,否則會報該文件已存在的異常FileSystem fileSystem = FileSystem.get(new URI(outputPath), conf);if (fileSystem.exists(new Path(outputPath))) {fileSystem.delete(new Path(outputPath), true);}//執(zhí)行jobjob.waitForCompletion(true);} }3.4.4?統(tǒng)計每門課程中相同分?jǐn)?shù)分布情況(Css)
package course_score_same;import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException;/* stu[0]:課程名稱 stu[1]:學(xué)生姓名 stu[2]:成績 stu[3]:性別 stu[4]:年齡 該功能實(shí)現(xiàn):統(tǒng)計該課程中成績相同的學(xué)生姓名*/ public class CssMapper extends Mapper<LongWritable, Text,Text,Text> {@Overrideprotected void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException {//將文件的每一行傳遞過來,使用split分割后利用字符數(shù)組進(jìn)行接收String[] stu = value.toString().split(",");//拼接字符串:課程和成績String sc = stu[0]+"\t"+stu[2];//向Reducer傳遞參數(shù)-> Key:課程+成績 Value:學(xué)生名context.write(new Text(sc),new Text(stu[1]));} } package course_score_same;import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException;public class CssReducer extends Reducer <Text,Text,Text,Text>{@Overrideprotected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {//創(chuàng)建StringBuffer用來接收該課程中成績相同的學(xué)生的姓名StringBuffer sb = new StringBuffer();//num變量用來計數(shù)int num = 0;//遍歷values參數(shù),將所有的value拼接進(jìn)sb,并統(tǒng)計學(xué)生數(shù)量for(Text value:values){sb.append(value.toString()).append(",");num++;}//如果num=1,則表明該課程的這個成績只有一個學(xué)生,否則就輸出if(num>1){String names = "一共有" + num + "名學(xué)生,他們的名字是:" +sb.toString();System.out.println("*************************************************");System.out.println(key.toString() + names);context.write(key,new Text(names));}} } package course_score_same;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import java.io.IOException; import java.net.URI; import java.net.URISyntaxException;public class CssMain {public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException, URISyntaxException {//創(chuàng)建job和“統(tǒng)計相同課程相同分?jǐn)?shù)的人數(shù)”任務(wù)入口Configuration conf = new Configuration();Job job = Job.getInstance(conf);job.setJarByClass(CssMain.class);//設(shè)置Mapper和Reducer的入口job.setMapperClass(CssMapper.class);job.setReducerClass(CssReducer.class);//設(shè)置Mapper的輸入輸出類型job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(Text.class);//設(shè)置Reducer的輸入輸出類型job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);//指定輸入輸出路徑String inputPath = "hdfs://localhost:9000/mapreduce/input/學(xué)生成績.csv";String outputPath = "hdfs://localhost:9000/mapreduce/output/該課程中成績相同的學(xué)生姓名.txt";FileInputFormat.setInputPaths(job,new Path(inputPath));FileOutputFormat.setOutputPath(job,new Path(outputPath));//輸出路徑存在的話就刪除,不然就只能手動刪除,否則會報該文件已存在的異常FileSystem fileSystem = FileSystem.get(new URI(outputPath), conf);if (fileSystem.exists(new Path(outputPath))) {fileSystem.delete(new Path(outputPath), true);}//執(zhí)行jobjob.waitForCompletion(true);} }3.4.5?統(tǒng)計各性別的人數(shù)及他們的姓名(Snn)
package sex_number_name;import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException;/* stu[0]:課程名稱 stu[1]:學(xué)生姓名 stu[2]:成績 stu[3]:性別 stu[4]:年齡 該功能實(shí)現(xiàn):各性別人數(shù)及他們的姓名*/ public class SnnMapper extends Mapper<LongWritable, Text,Text,Text> {@Overrideprotected void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException {//將文件的每一行傳遞過來,使用split分割后利用字符數(shù)組進(jìn)行接收String[] stu = value.toString().split(",");//向Reducer傳遞參數(shù)-> Key:性別 Value:姓名context.write(new Text(stu[3]),new Text(stu[1]));} } package sex_number_name;import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List;public class SnnReducer extends Reducer<Text,Text,Text,Text> {@Overrideprotected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {//創(chuàng)建集合來去除重復(fù)值(HashSet不允許重復(fù)值的存在,故可用來去重)List<String> names= new ArrayList<>();for (Text value:values){names.add(value.toString());}HashSet<String> singleNames = new HashSet(names);//創(chuàng)建StringBuffer用來接收同性別學(xué)生的姓名StringBuffer sb = new StringBuffer();//拼接學(xué)生姓名以及統(tǒng)計人數(shù)int num = 0;for(String singleName:singleNames){sb.append(singleName.toString()).append(",");num++;}//輸出String result = "生一共有" + num + "名,他們的名字是:" +sb.toString();System.out.println("********************************************");System.out.println(key.toString() + result);context.write(key,new Text(result));} } package sex_number_name;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import java.io.IOException; import java.net.URI; import java.net.URISyntaxException;public class SnnMain {public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException, URISyntaxException {//創(chuàng)建job和“統(tǒng)計相同課程相同分?jǐn)?shù)的人數(shù)”任務(wù)入口Configuration conf = new Configuration();Job job = Job.getInstance(conf);job.setJarByClass(SnnMain.class);//設(shè)置Mapper和Reducer的入口job.setMapperClass(SnnMapper.class);job.setReducerClass(SnnReducer.class);//設(shè)置Mapper的輸入輸出類型job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(Text.class);//設(shè)置Reducer的輸入輸出類型job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);//指定輸入輸出路徑String inputPath = "hdfs://localhost:9000/mapreduce/input/學(xué)生成績.csv";String outputPath = "hdfs://localhost:9000/mapreduce/output/各性別人數(shù)及他們的姓名.txt";FileInputFormat.setInputPaths(job,new Path(inputPath));FileOutputFormat.setOutputPath(job,new Path(outputPath));//輸出路徑存在的話就刪除,不然就只能手動刪除,否則會報該文件已存在的異常FileSystem fileSystem = FileSystem.get(new URI(outputPath), conf);if (fileSystem.exists(new Path(outputPath))) {fileSystem.delete(new Path(outputPath), true);}//執(zhí)行jobjob.waitForCompletion(true);} }3.4.6?統(tǒng)計每門課程信息(Ci)
package couerse_info;import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException; /* stu[0]:課程名稱 stu[1]:學(xué)生姓名 stu[2]:成績 stu[3]:性別 stu[4]:年齡 該功能實(shí)現(xiàn)的是:通過指定信息查找學(xué)生課程考試信息*/public class CiMapper extends Mapper<LongWritable,Text,Text,Text> {@Overrideprotected void map(LongWritable Key1, Text value1,Context context) throws IOException, InterruptedException {//將文件的每一行傳遞過來,使用split分割后利用字符數(shù)組進(jìn)行接收String[] splits= value1.toString().split(",");//拼接字符串:學(xué)生名和成績String course = splits[0];String name = splits[1];String score = splits[2];String course_info = name + ":" + score;//向Reducer傳遞參數(shù)-> Key:課程 Value:學(xué)生名+成績context.write(new Text(course),new Text(course_info));} } package couerse_info;import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException; import java.util.ArrayList; import java.util.List;public class ciReducer extends Reducer<Text, Text,Text, Text> {@Overrideprotected void reduce(Text key,Iterable<Text> values,Context context)throws IOException,InterruptedException{//拼接課程的學(xué)生姓名和成績String courseInfo = "\n";for(Text Info:values){courseInfo = courseInfo + Info + " ";}System.out.println(key.toString()+":"+courseInfo);System.out.println("***********************************************************************************************************************");context.write(key,new Text(courseInfo));} } package couerse_info;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import java.io.IOException; import java.net.URI; import java.net.URISyntaxException;public class CiMain {public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException, URISyntaxException {//創(chuàng)建job和“統(tǒng)計相同課程相同分?jǐn)?shù)的人數(shù)”任務(wù)入口Configuration conf = new Configuration();Job job = Job.getInstance(conf);job.setJarByClass(CiMain.class);//設(shè)置Mapper和Reducer的入口job.setMapperClass(CiMapper.class);job.setReducerClass(ciReducer.class);//設(shè)置Mapper的輸入輸出類型job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(Text.class);//設(shè)置Reducer的輸入輸出類型job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);//指定輸入輸出路徑String inputPath = "hdfs://localhost:9000/mapreduce/input/學(xué)生成績.csv";String outputPath = "hdfs://localhost:9000/mapreduce/output/課程信息.txt";FileInputFormat.setInputPaths(job,new Path(inputPath));FileOutputFormat.setOutputPath(job,new Path(outputPath));//輸出路徑存在的話就刪除,不然就只能手動刪除,否則會報該文件已存在的異常FileSystem fileSystem = FileSystem.get(new URI(outputPath), conf);if (fileSystem.exists(new Path(outputPath))) {fileSystem.delete(new Path(outputPath), true);}//執(zhí)行jobjob.waitForCompletion(true);} }4 運(yùn)行
5 改進(jìn)
????????至此一個完整的基于mapreduce的學(xué)生成績分析系統(tǒng)就算是基本完成了,當(dāng)然完成的功能還是十分的基礎(chǔ)。如果想要追求進(jìn)階操作,可以嘗試使用多重處理,即把一個甚至多個mapreduce處理得到的結(jié)果當(dāng)做是一個數(shù)據(jù)集,對該結(jié)果繼續(xù)進(jìn)行mapreduce分析。如果有意愿還可以再進(jìn)一步分析,反正越分析越詳細(xì),這可能就是你課設(shè)比別人突出的部分,是一個大大的加分項。?
總結(jié)
以上是生活随笔為你收集整理的【细节拉满】Hadoop课程设计项目,使用idea编写基于MapReduce的学生成绩分析系统(附带源码、项目文件下载地址)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: python 日志不会按照日期分割_dj
- 下一篇: 广电运通不好进吗_我可以说郑州新风的安装
