利用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é)果
具體代碼實現(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 {
//通過過冒號分割
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>();//實際生產(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去運行
//job.submit();無結(jié)果返回,建議不使用它
boolean res = job.waitForCompletion(true);
System.exit(res?0:1);
}
}
結(jié)果:

第二步:
代碼實現(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)行排序,防止計算數(shù)據(jù)重復(fù),例如:A-B和B-A其實一個對
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>();//實際生產(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去運行
//job.submit();無結(jié)果返回,建議不使用它
boolean res = job.waitForCompletion(true);
System.exit(res?0:1);
}
}
結(jié)果:

這樣就可以找到正確結(jié)果
總結(jié)
到此這篇關(guān)于利用hadoop查詢兩兩之間有共同好友及他倆的共同好友都是誰的文章就介紹到這了,更多相關(guān)Hadoop求共同好友內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
redis中存儲list<map>,list<entity>的處理
本文主要介紹了redis中存儲list<map>,list<entity>的處理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06
詳解Java的內(nèi)置異常以及創(chuàng)建自定義異常子類的方法
這篇文章主要介紹了詳解Java的內(nèi)置異常以及創(chuàng)建自定義異常子類的方法,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09
Java將不同的List集合復(fù)制到另一個集合常見的方法
在Java中,有時候我們需要將一個List對象的屬性值復(fù)制到另一個List對象中,使得兩個對象的屬性值相同,這篇文章主要介紹了Java將不同的List集合復(fù)制到另一個集合常見的方法,需要的朋友可以參考下2024-09-09
Mac配置 maven以及環(huán)境變量設(shè)置方式
這篇文章主要介紹了Mac配置 maven以及環(huán)境變量設(shè)置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08
SpringMVC框架和SpringBoot項目中控制器的響應(yīng)結(jié)果深入分析
這篇文章主要介紹了SpringMVC框架和SpringBoot項目中控制器的響應(yīng)結(jié)果,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-12-12
Spring Boot 整合mybatis 與 swagger2
之前使用springMVC+spring+mybatis,總是被一些繁瑣的xml配置,還經(jīng)常出錯,下面把以前的一些ssm項目改成了spring boot + mybatis,相對于來說優(yōu)點太明顯了,具體內(nèi)容詳情大家通過本文學(xué)習(xí)吧2017-08-08
SpringBoot項目啟動錯誤:找不到或無法加載主類的幾種解決方法
本文主要介紹了SpringBoot項目啟動錯誤:找不到或無法加載主類的幾種解決方法,具有一定的參考價值,感興趣的可以了解一下2025-03-03
spring-boot-maven-plugin:unknown的完美解決方法
這篇文章主要介紹了spring-boot-maven-plugin:unknown的完美解決方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11

