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

第一次先找出A、B、…是谁的好友

Mapper

public class SameFriendsFirstMapper extends Mapper<LongWritable, Text, Text, Text> {

    Text k = new Text();
    Text v = new Text();

    @Override
    protected void map (LongWritable key, Text value, Context context) throws IOException, InterruptedException {

        // A:B,C,D,F,E,O
        // A的好友有B,C,D,F,E,O
        // 找出X是谁的好友
        // 输出如<B,A>
        String line = value.toString();
        String[] fields = line.split(":");
        v.set(fields[0]);

        if (fields.length > 1) {
            String[] keyFields = fields[1].split(",");
            for (String keyField : keyFields) {
                k.set(keyField);

                context.write(k, v);
            }
        }
    }
}

Reducer

public class SameFriendsFirstReducer extends Reducer<Text, Text, Text, NullWritable> {

    Text k = new Text();

    @Override
    protected void reduce (Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {

        List<String> list = new ArrayList<>();
        for (Text value : values) {
            list.add(value.toString());
        }

        k.set(key.toString() + ":" + String.join(",", list));

        context.write(k, NullWritable.get());
    }
}

第一次运行结果如下:

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

Mapper

public class SameFriendsSecondMapper extends Mapper<LongWritable, Text, Text, Text> {

    Text k = new Text();
    Text v = new Text();

    @Override
    protected void map (LongWritable key, Text value, Context context) throws IOException, InterruptedException {

        // A:I,K,C,B,G,F,H,O,D
        // A是I,K,C,B,G,F,H,O,D的好友
        // 输出如<I-K, A>
        String line = value.toString();
        String[] fields = line.split(":");

        v.set(fields[0]);

        if (fields.length > 1) {
            String[] keyPreFields = fields[1].split(",");
            for (int i = 0; i < keyPreFields.length - 1; i++) {
                String first = keyPreFields[i];
                for (int j = i + 1; j < keyPreFields.length; j++) {
                    String second = keyPreFields[j];

                    // 防止出现A-D和D-A的情况
                    if (first.compareToIgnoreCase(second) < 0) {
                        k.set(first + "-" + second);
                    } else {
                        k.set(second + "-" + first);
                    }
                    context.write(k, v);
                }
            }
        }
    }
}

Reducer

public class SameFriendsSecondReducer extends Reducer<Text, Text, Text, Text> {

    Text v = new Text();

    @Override
    protected void reduce (Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {

        List<String> list = new ArrayList<>();
        for (Text value : values) {
            list.add(value.toString());
        }

        v.set(String.join(" ", list));

        context.write(key, v);
    }
}

第二次运行结果:

A-B	C E
A-C	D F
A-D	F E
A-E	B D C
A-F	C B O D E
A-G	F D E C
A-H	D O E C
A-I	O
A-J	O B
A-K	D C
A-L	E D F
A-M	F E
B-C	A
B-D	E A
B-E	C
B-F	E A C
B-G	C A E
B-H	E C A
B-I	A
B-K	C A
B-L	E
B-M	E
B-O	A
C-D	F A
C-E	D
C-F	D A
C-G	D F A
C-H	A D
C-I	A
C-K	D A
C-L	D F
C-M	F
C-O	I A
D-E	L
D-F	A E
D-G	E A F
D-H	E A
D-I	A
D-K	A
D-L	E F
D-M	E F
D-O	A
E-F	B M D C
E-G	D C
E-H	D C
E-J	B
E-K	D C
E-L	D
F-G	C D A E
F-H	A E O C D
F-I	O A
F-J	O B
F-K	A C D
F-L	E D
F-M	E
F-O	A
G-H	A D E C
G-I	A
G-K	C A D
G-L	F D E
G-M	F E
G-O	A
H-I	A O
H-J	O
H-K	A D C
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
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值