原文件
说明:
人物:好友1、好友2......
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
一、找出所有人两两之间的所有共同好友(包含两两认识和两两不认识)
解析:
第一阶段(TextInputFormat)
- map端
- 输入:<A,A的所有好友>
- 输出:<A的一位好友,A>
- reduce端
- 输入:<一位好友,拥有该好友的所有人>
- 输出:<人-人,一位共同好友>
第二阶段(KeyValueTextInputFormat)
- map端:无处理
- reduce端
- 输入:<人-人,一位共同好友>
- 输出:<人-人,所有共同好友>
数据示例:
A:B、C、D
B:A、C、D
C:A、B
第一阶段:
map端:
- 输入:<A , (B,C,D)>, <B , (A,C,D)>, <C , (A,B)>
- 输出:<B,A> , <C,A> , <D,A> , <A,B> , <C,B> , <D,B> , <A,C> , <B,C> ,
reduce端:
- 输入:<A,(B,C)> , <B,(A,C)> , <C,(A,B)> , <D,(A,B)>
- 输出:<B-C , A> , <A-C , B> , <A-B , C> , <A-B , D>
第二阶段:
map端:无变化
reduce端
- 输入=第一阶段reduce端的输出:<B-C , A> , <A-C , B> , <A-B , C> , <A-B , D>
- 输出:<A-B , CD> , <A-C , B> , <B-C , A>
代码实现:
第一阶段:
/*
* Mapper
* 输入 <人,该人的所有好友>
* 输出 <该人的一位好友,人>
*/
public class Mapper01 extends Mapper<LongWritable ,Text,Text,Text>{
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
StringTokenizer str1 = new StringTokenizer(value.toString(),":");
//取到人
Text name = new Text(str1.nextToken());
StringTokenizer str2 = new StringTokenizer(str1.nextToken(),",");
while(str2.hasMoreTokens()){
//该人对应的一位好友
Text friend = new Text(str2.nextToken());
//输出:<人,该人的一位好友>
context.write(friend, name);
}
}
}
输出结果:
A I
A K
A C
A B
A G
A F
A H
A O
A D
B A
B F
B J
B E
C A
C E
C B
C H
C F
C G
C K
D G
D C
D K
D A
D L
D F
D E
D H
E G
E M
E L
E H
E A
E F
E B
E D
F L
F M
F D
F C
F G
F A
G M
H O
I O
I C
J O
K B
L D
L E
M E
M F
O A
O H
O I
O J
O F
/*
* Reducer
* 输入 <一位好友,拥有该好友的所有人)>
* 输出 <人-人,一位好友>
*/
public class Reducer01 extends Reducer<Text, Text, Text, Text>{
@Override
protected void reduce(Text key, Iterable<Text> value, Reducer<Text, Text, Text, Text>.Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
ArrayList<Text> a = new ArrayList<Text>();
for(Text name:value){
Text n = new Text(name.toString());
a.add(n);
}
for(int i=0;i<a.size();i++){
for(int j=i+1;j<a.size();j++){
Text t = new Text();
Text x = a.get(i);
Text y = a.get(j);
//按照字母表顺序排序(即按照ASC码)
if(x.toString().charAt(0)>y.toString().charAt(0))