Java操作Spark简单案例《好友推荐》

前言

  由于Scala语言编写Spark应用程序的便捷性。之前的案例操作都是用的Scala语言。但是由于大部分人都是学的Java,这里我使用Java编写了一个简单的Spark应用程序。如有不足,敬请指正!!!

数据介绍

  输入数据如下所示:

hello  hadoop  cat
world  hadoop  hello  hive
cat  tom  hive
mr  hive  hello
hive  cat  hadoop  world  hello  mr
hadoop  tom  hive  world
hello  tom  world  hive  mr

  下面我解释一下上面数据的含义。就拿第二行来说:这个人叫world,他有三个好友,分别是:hadoop、hello和hive。hadoop、hello和hive之间就是间接好友。


  在经历下面的程序之后,输出的数据如下:

mr_cat:1
world_tom:2
tom_hive:3
hello_hadoop:3
tom_mr:1
mr_hadoop:1
hello_cat:2
hadoop_cat:2
world_cat:1
world_mr:2

程序介绍

  在上面的介绍中,我们知道了什么是直接好友与间接好友。在A的关系中,C和D是间接好友,在B的关系中,C和D也可能是间接好友。所以我们这个程序就是求出这种间接好友的数量。这对间接好友关系出现的次数越多、频率越高。这对间接好友就越有价值。

  注意:A和B是间接好友的话,B和A也是间接好友,这两对间接好友对我们来说都是一样的意思,可是却分开进行统计,这样的结果显然不是我们想要的。
  为了解决这个问题,我设计了一个String字符串拼接。如果A和B是间接好友,就根据某个规则来设计为:A_B。详情如下代码:

public static String addStr(String str1,String str2){
    if(str1.compareTo(str2) >= 0){
    	return str1 + "_" + str2;
    }else{
   		return str2 + "_" + str1;
   	}	
 }

代码区

package com.hpe.spark.instane;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.PairFlatMapFunction;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.api.java.function.VoidFunction;

import scala.Tuple2;

public class Fof {
	public static void main(String[] args) {
		SparkConf conf = new SparkConf();
		conf.setMaster("local");
		conf.setAppName("Fof");
		
		//在java中声明应用上下文
		@SuppressWarnings("resource")
		JavaSparkContext jsc = new JavaSparkContext(conf);
		jsc.setLogLevel("WARN");
		
		//获取初始RDD
		JavaRDD<String> rdd = jsc.textFile("d:/data/friend.txt");
		
		
		//分词,直接好友计数为0,间接好友计数为1
		JavaPairRDD<String, Integer> flatMapToPairRDD = rdd.flatMapToPair(new PairFlatMapFunction<String, String, Integer>() {

			private static final long serialVersionUID = 1L;

			@Override
			public Iterable<Tuple2<String, Integer>> call(String input)
					throws Exception {
				List<Tuple2<String, Integer>> list = new ArrayList<Tuple2<String, Integer>>();
				String[] words = input.split("\t");
				String me = words[0];
				for (int i=1 ; i<words.length ; i++ ) {
					list.add(new Tuple2<String, Integer>(addStr(me,words[i]), 0));
					for(int j=i+1 ; j<words.length ; j++){
						list.add(new Tuple2<String, Integer>(addStr(words[j],words[i]), 1));
					}
				}
				
				return list;
			}
		});
		
		//分组
		JavaPairRDD<String, Iterable<Integer>> groupByKeyRDD = flatMapToPairRDD.groupByKey();
		
		//同一组内的数据若有直接好友关系,整组删除。否则计数累加
		JavaPairRDD<String, Integer> javaPairRDD = groupByKeyRDD.mapToPair(new PairFunction<Tuple2<String,Iterable<Integer>>, String, Integer>() {

			private static final long serialVersionUID = 1L;

			@Override
			public Tuple2<String, Integer> call(
					Tuple2<String, Iterable<Integer>> values) throws Exception {
				boolean bool = false;
				int count = 0;
				
				String name = values._1;
				Iterable<Integer> flags = values._2;
				
				//统计间接好友出现的次数
				for (Integer flag : flags) {
					if(flag == 0){
						bool = true;
					}
					count++;
				}
				
				//如果不是直接好友,就是间接好友,只返回间接好友
				if(bool == false){
					return new Tuple2<String, Integer>(name, count);
				} else{
					return new Tuple2<String, Integer>("直接好友", 0);
				}
			}
		});
		
		//输出
		javaPairRDD.foreach(new VoidFunction<Tuple2<String,Integer>>() {

			private static final long serialVersionUID = 1L;

			@Override
			public void call(Tuple2<String, Integer> friend) throws Exception {
				if(friend._2 != 0){
					System.out.println(friend._1 + ":" + friend._2);
				}
			}
		});
		
		//释放资源
		jsc.stop();
		
	}
	
	//拼接字符串
	public static String addStr(String str1,String str2){
		if(str1.compareTo(str2) >= 0){
			return str1 + "_" + str2;
		}else{
			return str2 + "_" + str1;
		}	
	}
	
}
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值