求所有两两用户之间的共同好友

数据格式

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,K

以上是数据:
A:B,C,D,F,E,O
表示:B,C,D,E,F,O是A用户的好友。

 public class SharedFriend {
/*
第一阶段的map函数主要完成以下任务
1.遍历原始文件中每行<所有朋友>信息
2.遍历“朋友”集合,以每个“朋友”为键,原来的“人”为值 即输出<朋友,人>
*/
static class SharedFriendMapper01 extends Mapper<LongWritable, Text, Text, Text>{
@Override
protected void map(LongWritable key, Text value,Context context)
throws IOException, InterruptedException {
String line = value.toString();
String[] person_friends = line.split(":");
String person = person_friends[0];
String[] friends = person_friends[1].split(","); for(String friend : friends){
context.write(new Text(friend), new Text(person));
}
}
} /*
第一阶段的reduce函数主要完成以下任务
1.对所有传过来的<朋友,list(人)>进行拼接,输出<朋友,拥有这名朋友的所有人>
*/
static class SharedFriendReducer01 extends Reducer<Text, Text, Text, Text>{
@Override
protected void reduce(Text key, Iterable<Text> values,Context context)
throws IOException, InterruptedException {
StringBuffer sb = new StringBuffer();
for(Text friend : values){
sb.append(friend.toString()).append(",");
}
sb.deleteCharAt(sb.length()-1);
context.write(key, new Text(sb.toString()));
}
} /*
第二阶段的map函数主要完成以下任务
1.将上一阶段reduce输出的<朋友,拥有这名朋友的所有人>信息中的 “拥有这名朋友的所有人”进行排序 ,以防出现B-C C-B这样的重复
2.将 “拥有这名朋友的所有人”进行两两配对,并将配对后的字符串当做键,“朋友”当做值输出,即输出<人-人,共同朋友>
*/
static class SharedFriendMapper02 extends Mapper<LongWritable, Text, Text, Text>{
@Override
protected void map(LongWritable key, Text value,Context context)
throws IOException, InterruptedException {
String line = value.toString();
String[] friend_persons = line.split("\t");
String friend = friend_persons[0];
String[] persons = friend_persons[1].split(",");
Arrays.sort(persons); //排序 //两两配对
for(int i=0;i<persons.length-1;i++){
for(int j=i+1;j<persons.length;j++){
context.write(new Text(persons[i]+"-"+persons[j]+":"), new Text(friend));
}
}
}
} /*
第二阶段的reduce函数主要完成以下任务
1.<人-人,list(共同朋友)> 中的“共同好友”进行拼接 最后输出<人-人,两人的所有共同好友>
*/
static class SharedFriendReducer02 extends Reducer<Text, Text, Text, Text>{
@Override
protected void reduce(Text key, Iterable<Text> values,Context context)
throws IOException, InterruptedException {
StringBuffer sb = new StringBuffer();
Set<String> set = new HashSet<String>();
for(Text friend : values){
if(!set.contains(friend.toString()))
set.add(friend.toString());
}
for(String friend : set){
sb.append(friend.toString()).append(",");
}
sb.deleteCharAt(sb.length()-1); context.write(key, new Text(sb.toString()));
}
} public static void main(String[] args)throws Exception {
Configuration conf = new Configuration(); //第一阶段
Job job1 = Job.getInstance(conf);
job1.setJarByClass(SharedFriend.class);
job1.setMapperClass(SharedFriendMapper01.class);
job1.setReducerClass(SharedFriendReducer01.class); job1.setOutputKeyClass(Text.class);
job1.setOutputValueClass(Text.class); FileInputFormat.setInputPaths(job1, new Path("H:/大数据/mapreduce/sharedfriend/input"));
FileOutputFormat.setOutputPath(job1, new Path("H:/大数据/mapreduce/sharedfriend/output")); boolean res1 = job1.waitForCompletion(true); //第二阶段
Job job2 = Job.getInstance(conf);
job2.setJarByClass(SharedFriend.class);
job2.setMapperClass(SharedFriendMapper02.class);
job2.setReducerClass(SharedFriendReducer02.class); job2.setOutputKeyClass(Text.class);
job2.setOutputValueClass(Text.class); FileInputFormat.setInputPaths(job2, new Path("H:/大数据/mapreduce/sharedfriend/output"));
FileOutputFormat.setOutputPath(job2, new Path("H:/大数据/mapreduce/sharedfriend/output01")); boolean res2 = job2.waitForCompletion(true); System.exit(res1?0:1);
}
}

第一阶段输出结果

 A    F,I,O,K,G,D,C,H,B
B E,J,F,A
C B,E,K,A,H,G,F
D H,C,G,F,E,A,K,L
E A,B,L,G,M,F,D,H
F C,M,L,A,D,G
G M
H O
I O,C
J O
K O,B
L D,E
M E,F
O A,H,I,J,F

第二阶段输出结果

 A-B    C,E
A-C D,F
A-D E,F
A-E C,B,D
A-F E,O,C,D,B
A-G F,C,E,D
A-H D,O,C,E
A-I O
A-J B,O
A-K C,D
A-L D,E,F
A-M E,F
B-C A
B-D A,E
B-E C
B-F A,C,E
B-G E,C,A
B-H A,E,C
B-I A
B-K A,C
B-L E
B-M E
B-O K,A
C-D F,A
C-E D
C-F D,A
C-G D,F,A
C-H D,A
C-I A
C-K A,D
C-L D,F
C-M F
C-O I,A
D-E L
D-F A,E
D-G F,A,E
D-H A,E
D-I A
D-K A
D-L F,E
D-M F,E
D-O A
E-F C,D,M,B
E-G C,D
E-H C,D
E-J B
E-K D,C
E-L D
F-G C,E,D,A
F-H D,O,A,E,C
F-I A,O
F-J O,B
F-K D,C,A
F-L D,E
F-M E
F-O A
G-H E,C,D,A
G-I A
G-K D,A,C
G-L F,E,D
G-M E,F
G-O A
H-I A,O
H-J O
H-K C,D,A
H-L D,E
H-M E
H-O A
I-J O
I-K A
I-O A
K-L D
K-O A
L-M F,E

Hadoop学习之路(二十八)MapReduce的API使用(五)的更多相关文章

  1. Hadoop学习之路(十八)MapReduce框架Combiner分区

    对combiner的理解 combiner其实属于优化方案,由于带宽限制,应该尽量map和reduce之间的数据传输数量.它在Map端把同一个key的键值对合并在一起并计算,计算规则与reduce一致 ...

  2. FastAPI 学习之路(十八)表单与文件

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  3. Hadoop学习之路(十三)MapReduce的初识

    MapReduce是什么 首先让我们来重温一下 hadoop 的四大组件: HDFS:分布式存储系统 MapReduce:分布式计算系统 YARN:hadoop 的资源调度系统 Common:以上三大 ...

  4. Dynamic CRM 2013学习笔记(二十八)用JS动态设置字段的change事件、必填、禁用以及可见

    我们知道通过界面设置字段的change事件,是否是必填,是否可见非常容易.但有时我们需要动态地根据某些条件来设置,这时有需要通过js来动态地控制了. 下面分别介绍如何用js来动态设置.   一.动态设 ...

  5. Hadoop学习之路(十二)分布式集群中HDFS系统的各种角色

    NameNode 学习目标 理解 namenode 的工作机制尤其是元数据管理机制,以增强对 HDFS 工作原理的 理解,及培养 hadoop 集群运营中“性能调优”.“namenode”故障问题的分 ...

  6. Hadoop学习之路(十五)MapReduce的多Job串联和全局计数器

    MapReduce 多 Job 串联 需求 一个稍复杂点的处理逻辑往往需要多个 MapReduce 程序串联处理,多 job 的串联可以借助 MapReduce 框架的 JobControl 实现 实 ...

  7. Hadoop学习之路(十四)MapReduce的核心运行机制

    概述 一个完整的 MapReduce 程序在分布式运行时有两类实例进程: 1.MRAppMaster:负责整个程序的过程调度及状态协调 2.Yarnchild:负责 map 阶段的整个数据处理流程 3 ...

  8. Hadoop学习之路(十九)MapReduce框架排序

    流量统计项目案例 样本示例 需求 1. 统计每一个用户(手机号)所耗费的总上行流量.总下行流量,总流量 2. 得出上题结果的基础之上再加一个需求:将统计结果按照总流量倒序排序 3. 将流量汇总统计结果 ...

  9. Spark学习之路 (十八)SparkSQL简单使用

    一.SparkSQL的进化之路 1.0以前: Shark 1.1.x开始: SparkSQL(只是测试性的)  SQL 1.3.x: SparkSQL(正式版本)+Dataframe 1.5.x: S ...

  10. Spark学习之路 (十八)SparkSQL简单使用[转]

    SparkSQL的进化之路 1.0以前: Shark 1.1.x开始: SparkSQL(只是测试性的) SQL 1.3.x: SparkSQL(正式版本)+Dataframe 1.5.x: Spar ...

随机推荐

  1. protobuf简单测试应用

    protobuf是google推出的一种数据交换协议,比较适合应用于底层服务交互,nodejs提供protobufjs包的实现,下面是一个简单的测试demo: 首先是.proto文件: package ...

  2. 记一次C#面试

    最近参加了工作后的第一次面试,虽然最终没谈成,但是收获还是不少,不管是技术还是面试经验还是得多多积累呀. 这一次面试与在学校时候参加过的面试区别还是挺大的.校园招聘的面试问的问题似乎都比较具体,直接针 ...

  3. 三、hdfs的JavaAPI操作

    下文展示Java的API如何操作hdfs,在这之前你需要先安装配置好hdfs https://www.cnblogs.com/lay2017/p/9919905.html 依赖 你需要引入依赖如下 & ...

  4. IDEA快捷键使用说明

    sout :  输出打印语句 System.out.println(); "内容".sout  : 也是打印 System.out.println("内容"); ...

  5. java核心技术-NIO

    1.reactor(反应器)模式 使用单线程模拟多线程,提高资源利用率和程序的效率,增加系统吞吐量.下面例子比较形象的说明了什么是反应器模式: 一个老板经营一个饭店, 传统模式 - 来一个客人安排一个 ...

  6. python模块之numpy与pandas

    一.numpy numpy是python数据分析和机器学习的基础模块之一.它有两个作用:1.区别于list列表,提供了数组操作.数组运算.以及统计分布和简单的数学模型:2.计算速度快[甚至要由于pyt ...

  7. 【SSH网上商城项目实战26】完成订单支付后的短信发送功能

     转自: https://blog.csdn.net/eson_15/article/details/51475431 上一节我们使用了Java mail完成了给买家发送邮件的功能,还遗留一个功能,就 ...

  8. JavaScript中各存在性函数

    JavaScript中有很多表示存在性和从属关系的函数,本文介绍如下几个: 1)有关实例与构造函数原型之间的关系:isPrototypeOf(),Object.getPrototypeOf(); 2) ...

  9. C# 读取excel用户列表过滤一个月内未收到外部邮件已离职的员工

    1.通过aspose.cells读取excel中的数据并添加到list中 //存储从excel中读取出来的数据 List<UserInfo> lst_userinfo = new List ...

  10. Teamviewer 手机端怎么使用右键-已解决

    Teamviewer 手机端怎么使用右键 可能很多人和我一样,关掉了那个提示,然后记不住操作 怎么控制电脑使用右键? 长按就可以了 拖到指定地点,然后长按不送,就会出来电脑右键菜单