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

数据格式

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. github flow

    github flow Github flow 是Git flow的简化版,专门配合"持续发布".它是 Github.com 使用的工作流程 它只有一个长期分支,就是master, ...

  2. 撩课-Java每天5道面试题第15天

    撩课Java+系统架构点击开始学习 106.什么是Hibernate的并发机制?怎么去处理并发问题? a.Hibernate的Session对象是非线程安全的, 对于单个请求,单个会话, 单个的工作单 ...

  3. fuzhou 1692 Key problem ***

    Problem 1692 Key problem Accept: 103    Submit: 553 Time Limit: 1000 mSec    Memory Limit : 32768 KB ...

  4. uva 725 DIVISION (暴力枚举)

    我的56MS #include <cstdio> #include <iostream> #include <string> #include <cstrin ...

  5. C++输入输出流--<iostream>详解

    C++输入输出流包含在头文件<iostream>中, 流的定义如下:通过设备驱动程序与键盘.屏幕.文件.打印机等进行交互, iostream 类提供与之交互的方法.输出流:输出流的对象是字 ...

  6. [转]Tips——Chrome DevTools - 25 Tips and Tricks

    Chrome DevTools - 25 Tips and Tricks 原文地址:https://www.keycdn.com/blog/chrome-devtools 如何打开? 1.从浏览器菜单 ...

  7. 004bean作用域

    1.Singleton(单例) 2.Prototype(原型)---->每次注入.通过Spring应用上下文获取,都会重新创建    @Scope(ConfigurableBeanFactory ...

  8. Spring Data MongoDB 模糊查询

    Pattern pattern = Pattern.compile("^.*" + value + ".*$"); Query query = new Quer ...

  9. 微服务架构之spring cloud turbine

    在前面介绍了spring cloud hystrix及其hystrix dashboard,但都是对单个项目的监控,对于一个为项目而言,必定有很多微服务,一个一个去看非常的不方便,如果有一个能集中熔断 ...

  10. Android碎笔录3——点击跳转

    只要是view都能设置点击事件,不必要非得是Button. 要想实现跳转得三步走: 第一步.绑定 每个Layout都有一个一个java文件跟它绑定,这个Layout相关的代码都写在这个java文件里 ...