利用hadoop查詢兩兩之間有共同好友及他倆的共同好友都是誰
A:B,C,D,F,E,O
B:A,C,E,K
C:F,A,D,I
D:A,E,F,L
E:B,C,D,M,L
F:A,B,C,D,E,O,M
G:A,C,D,E,F
H:A,C,D,E,O
I:A,O
J:B,O
K:A,C,D
L:D,E,F
M:E,F,G
O:A,H,I,J
該數(shù)據(jù)可以看作好友,例如:A有B,C,D,F,E,O好友;B有A,C,E,K好友,以此類推;
求兩兩之間有共同好友,及他倆的共同好友都是誰,例如:A和B之間共同好友是:C、E
編碼思路:
第一步是可以把好友當(dāng)作key,value是擁有key好友的用戶,例如:擁有好友B的是:A,F,J,E用戶
第二步在第一步結(jié)果后,雙重for循環(huán)進(jìn)行兩兩之間進(jìn)行拼接,這樣就可以得出正確結(jié)果
具體代碼實(shí)現(xiàn):
第一步:
package com.zsy.mr.commonfriend; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; 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 commonFriendStepOne { static class commonFriendStepOneMapper extends Mapper<LongWritable, Text, Text, Text>{ Text k = new Text(); Text v = new Text(); @Override protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context) throws IOException, InterruptedException { //通過過冒號(hào)分割 String[] splits = value.toString().split(":"); //獲取擁有好友的用戶名 String name = splits[0]; //獲取該用戶下的好友列表 String[] friends = StringUtils.isNotBlank(splits[1])? splits[1].split(","):null; if(friends != null) { //循環(huán)好友,好友當(dāng)作key,擁有好友的用戶名當(dāng)作value for (String friend : friends) { k.set(friend); v.set(name); context.write(k, v); } } } } static class commonFriendStepOneReducer extends Reducer<Text, Text, Text, Text>{ Text v = new Text(); @Override protected void reduce(Text key, Iterable<Text> values, Reducer<Text, Text, Text, Text>.Context context) throws IOException, InterruptedException { List<String> resultList = new ArrayList<String>();//實(shí)際生產(chǎn)代碼不建議用list接收,應(yīng)該是直接處理掉 //處理數(shù)據(jù),該數(shù)據(jù)是擁有key好友的所有用戶 for (Text value : values) { resultList.add(value.toString()); } v.set(StringUtils.join(resultList, ",")); context.write(key, v); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); /*conf.set("mapreduce.framework.name", "yarn"); conf.set("yarn.resoucemanger.hostname", "hadoop01");*/ Job job = Job.getInstance(conf); job.setJarByClass(commonFriendStepOne.class); //指定本業(yè)務(wù)job要使用的業(yè)務(wù)類 job.setMapperClass(commonFriendStepOneMapper.class); job.setReducerClass(commonFriendStepOneReducer.class); //指定mapper輸出的k v類型 如果map的輸出和reduce的輸出一樣,只需要設(shè)置輸出即可 //job.setMapOutputKeyClass(Text.class); //job.setMapOutputValueClass(IntWritable.class); //指定最終輸出kv類型(reduce輸出類型) job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); //指定job的輸入文件所在目錄 FileInputFormat.setInputPaths(job, new Path(args[0])); //指定job的輸出結(jié)果目錄 FileOutputFormat.setOutputPath(job, new Path(args[1])); //將job中配置的相關(guān)參數(shù),以及job所有的java類所在 的jar包,提交給yarn去運(yùn)行 //job.submit();無結(jié)果返回,建議不使用它 boolean res = job.waitForCompletion(true); System.exit(res?0:1); } }
結(jié)果:
第二步:
代碼實(shí)現(xiàn)
package com.zsy.mr.commonfriend; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.commons.lang.StringUtils; 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.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 commonFriendStepTwo { static class commonFriendStepTwoMapper extends Mapper<LongWritable, Text, Text, Text>{ Text k = new Text(); Text v = new Text(); @Override protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context) throws IOException, InterruptedException { String[] splits = value.toString().split("\t"); //獲取好友 String friend = splits[0]; //獲取擁有該好友所有的用戶信息 String[] names = splits[1].split(","); //進(jìn)行排序,防止計(jì)算數(shù)據(jù)重復(fù),例如:A-B和B-A其實(shí)一個(gè)對(duì) Arrays.sort(names); //進(jìn)行雙重for循環(huán) for (int i = 0; i < names.length-1; i++) { String string = names[i]; for (int j = i+1; j < names.length; j++) { String string2 = names[j]; k.set(string+"-"+string2); v.set(friend); context.write(k, v); } } } } static class commonFriendStepTwoReducer extends Reducer<Text, Text, Text, NullWritable>{ Text k = new Text(); @Override protected void reduce(Text key, Iterable<Text> value, Reducer<Text, Text, Text, NullWritable>.Context context) throws IOException, InterruptedException { List<String> resultList = new ArrayList<String>();//實(shí)際生產(chǎn)代碼不建議用list接收,應(yīng)該是直接處理掉 for (Text text : value) { resultList.add(text.toString()); } k.set(key.toString()+":"+ StringUtils.join(resultList,",")); context.write(k, NullWritable.get()); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); /*conf.set("mapreduce.framework.name", "yarn"); conf.set("yarn.resoucemanger.hostname", "hadoop01");*/ Job job = Job.getInstance(conf); job.setJarByClass(commonFriendStepTwo.class); //指定本業(yè)務(wù)job要使用的業(yè)務(wù)類 job.setMapperClass(commonFriendStepTwoMapper.class); job.setReducerClass(commonFriendStepTwoReducer.class); //指定mapper輸出的k v類型 如果map的輸出和reduce的輸出一樣,只需要設(shè)置輸出即可 job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(Text.class); //指定最終輸出kv類型(reduce輸出類型) job.setOutputKeyClass(Text.class); job.setOutputValueClass(NullWritable.class); //指定job的輸入文件所在目錄 FileInputFormat.setInputPaths(job, new Path(args[0])); //指定job的輸出結(jié)果目錄 FileOutputFormat.setOutputPath(job, new Path(args[1])); //將job中配置的相關(guān)參數(shù),以及job所有的java類所在 的jar包,提交給yarn去運(yùn)行 //job.submit();無結(jié)果返回,建議不使用它 boolean res = job.waitForCompletion(true); System.exit(res?0:1); } }
結(jié)果:
這樣就可以找到正確結(jié)果
總結(jié)
到此這篇關(guān)于利用hadoop查詢兩兩之間有共同好友及他倆的共同好友都是誰的文章就介紹到這了,更多相關(guān)Hadoop求共同好友內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
輕量級(jí)聲明式的Http庫——Feign的獨(dú)立使用
這篇文章主要介紹了輕量級(jí)聲明式的Http庫——Feign的使用教程,幫助大家更好的理解和學(xué)習(xí)使用feign,感興趣的朋友可以了解下2021-04-04解決springboot服務(wù)啟動(dòng)報(bào)錯(cuò):Unable?to?start?embedded?contain
這篇文章主要介紹了解決springboot服務(wù)啟動(dòng)報(bào)錯(cuò):Unable?to?start?embedded?contain的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08SpringBoot與Spring中數(shù)據(jù)緩存Cache超詳細(xì)講解
我們知道內(nèi)存讀取速度遠(yuǎn)大于硬盤讀取速度,當(dāng)需要重復(fù)獲取相同數(shù)據(jù)時(shí),一次一次的請(qǐng)求數(shù)據(jù)庫或者遠(yuǎn)程服務(wù),導(dǎo)致在數(shù)據(jù)庫查詢或者遠(yuǎn)程方法調(diào)用上小號(hào)大量的時(shí)間,最終導(dǎo)致程序性能降低,這就是數(shù)據(jù)緩存要解決的問題,學(xué)過計(jì)算機(jī)組成原理或者操作系統(tǒng)的同學(xué)們應(yīng)該比較熟悉2022-10-10Java技能點(diǎn)之SimpleDateFormat進(jìn)行日期格式化問題
這篇文章主要介紹了Java技能點(diǎn)之SimpleDateFormat進(jìn)行日期格式化問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04springmvc參數(shù)為對(duì)象,數(shù)組的操作
這篇文章主要介紹了springmvc參數(shù)為對(duì)象,數(shù)組的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08RxJava2.x+ReTrofit2.x多線程下載文件的示例代碼
本篇文章主要介紹了RxJava2.x+ReTrofit2.x多線程下載文件的示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下2017-09-09