求好友中互粉的好友對
阿新 • • 發佈:2018-11-20
好友列表:
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,而B裡面好友有A,那麼A跟B就是互為好友。
我們的Map過程:
將好友列表檔案的每一行資料都進行提取出來,提取成好友:
A:B,C,D,F,E,O
經過Map就變成:
<A-B,NULL> <A-C,NULL> <A-D,NULL> <A-F,NULL> <A-E,NULL> <A-O,NULL>
B:A,C,E,K
經過Map就變成
<A-B.NULL>
<B-C,NULL>
<B-E,NULL>
<B-K,NULL>
static class EachFanMapper extends Mapper<LongWritable, Text, Text, NullWritable> { Text k = new Text(); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); String user = line.split(":")[0]; String[] friends = line.split(":")[1].split(","); for(int i = 0; i < friends.length; i++) { String friend = friends[i]; /** * 下面這個過程就是關鍵的過程, * 第一行資料 : A:B,C,D,F,E,O * 第二行資料 :B:A,C,E,K * A裡面有B,B裡面有A * 現在我們需要獲取這兩個 * 那麼我們在map的時候, user 跟 friend 進行組合往reduce輸出的時候, * 我們組合的時候需要進行排序, * 第一行資料組合 A-B * 第二行如果沒有排序 那麼就是 B-A * 但是我們在reduce進行處理時,需要的是相同的key * 那麼我們應該讓 A-B 與 B-A 變成同一個key往reduce輸出 * 這樣reduce才能根據相同的key進行數量的統計 * 當數量為2時,就代表,A-B出現了兩次,那麼這一對手機互相關注的。 */ if(user.compareTo(friend) < 0) { k.set(user + "-" + friend); context.write(k, NullWritable.get()); } else { k.set(friend + "-" + user); context.write(k, NullWritable.get()); } } } }
reduce
static class EachFanReducer extends Reducer<Text, NullWritable, Text, NullWritable> { @Override protected void reduce(Text key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException { int count = 0; for(NullWritable nw : values) { count++; } /** * 嚴格來說,這個count要麼為1 要麼為 2,當為2的時候,就說明是互粉 */ if(count == 2) { context.write(key, NullWritable.get()); } } }
程式碼
https://gitee.com/tanghongping/hadoopMapReduce/tree/master/src/com/thp/bigdata/eachFan