主要講解一下
map,filter,flatMap,groupByKey,reduceByKey,sortByKey,join,cogroup
map講解
List<Integer> list= Arrays.asList(1,2,3,4,5,6,7,8,9,10);
JavaRDD<Integer> line=sc.parallelize(list);
// 使用map算子,將集合中的每個元素都乘以2
// map算子,是對任何類型的RDD,都可以調用的
// 在java中,map算子接收的參數是Function對象
// 創建的Function對象,一定會讓你設置第二個泛型參數,這個泛型類型,就是返回的新元素的類型
// 同時call()方法的返回類型,也必須與第二個泛型類型同步
// 在call()方法內部,就可以對原始RDD中的每一個元素進行各種處理和計算,並返回一個新的元素
// 所有新的元素就會組成一個新的RDD
JavaRDD<Integer> lineM=line.map(new Function<Integer, Integer>() {
@Override
public Integer call(Integer i) throws Exception {
return i*2;
}
});
filter講解
// 對初始RDD執行filter算子,過濾出其中的偶數
// filter算子,傳入的也是Function,其他的使用注意點,實際上和map是一樣的
// 但是,唯一的不同,就是call()方法的返回類型是Boolean
// 每一個初始RDD中的元素,都會傳入call()方法,此時你可以執行各種自定義的計算邏輯
// 來判斷這個元素是否是你想要的
// 如果你想在新的RDD中保留這個元素,那麼就返回true;否則,不想保留這個元素,返回false
JavaRDD<Integer> lineeven=line.filter(new Function<Integer, Boolean>() {
@Override
public Boolean call(Integer i) throws Exception {
return i%2==0;
}
});
flatMap講解
List<String> lists= Arrays.asList("hello you","hello me");
JavaRDD<String> linestring=sc.parallelize(lists);
// 對RDD執行flatMap算子,將每一行文本,拆分爲多個單詞
// flatMap算子,在java中,接收的參數是FlatMapFunction
// 我們需要自己定義FlatMapFunction的第二個泛型類型,即,代表了返回的新元素的類型
// call()方法,返回的類型,不是U,而是Iterable<U>,這裏的U也與第二個泛型類型相同
// flatMap其實就是,接收原始RDD中的每個元素,並進行各種邏輯的計算和處理,返回可以返回多個元素
// 多個元素,即封裝在Iterable集合中,可以使用ArrayList等集合
// 新的RDD中,即封裝了所有的新元素;也就是說,新的RDD的大小一定是 >= 原始RDD的大小
JavaRDD<String> lines=linestring.flatMap(new FlatMapFunction<String, String>() {
@Override
public Iterable<String> call(String s) throws Exception {
return Arrays.asList(s.split(" "));
}
});
groupByKey講解
List<Tuple2<String,Integer>> sorce=Arrays.asList(new Tuple2<String, Integer>("one",85),
new Tuple2<String, Integer>("two",95),
new Tuple2<String, Integer>("one",90),
new Tuple2<String, Integer>("two",70)
);
// 針對scores RDD,執行groupByKey算子,對每個班級的成績進行分組
// groupByKey算子,返回的還是JavaPairRDD
// 但是,JavaPairRDD的第一個泛型類型不變,第二個泛型類型變成Iterable這種集合類型
// 也就是說,按照了key進行分組,那麼每個key可能都會有多個value,此時多個value聚合成了Iterable
// 那麼接下來,我們是不是就可以通過so這種JavaPairRDD,很方便地處理某個分組內的數據
JavaPairRDD<String,Integer> sorces=sc.parallelizePairs(sorce);
JavaPairRDD<String,Iterable<Integer>> so=sorces.groupByKey();
so.foreach(new VoidFunction<Tuple2<String, Iterable<Integer>>>() {
@Override
public void call(Tuple2<String, Iterable<Integer>> s) throws Exception {
System.out.println("key is:"+s._1);
Iterator<Integer> s1=s._2.iterator();
int sum=0;
while(s1.hasNext()){
sum=sum+s1.next();
}
System.out.println(sum);
}
});
reduceByKey講解
// 針對sorces RDD,執行reduceByKey算子
// reduceByKey,接收的參數是Function2類型,它有三個泛型參數,實際上代表了三個值
// 第一個泛型類型和第二個泛型類型,代表了原始RDD中的元素的value的類型
// 因此對每個key進行reduce,都會依次將第一個、第二個value傳入,將值再與第三個value傳入
// 因此此處,會自動定義兩個泛型類型,代表call()方法的兩個傳入參數的類型
// 第三個泛型類型,代表了每次reduce操作返回的值的類型,默認也是與原始RDD的value類型相同的
// reduceByKey算法返回的RDD,還是JavaPairRDD<key, value>
sorces.reduceByKey(new Function2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer v1, Integer v2) throws Exception {
// 對每個key,都會將其value,依次傳入call方法
// 從而聚合出每個key對應的一個value
// 然後,將每個key對應的一個value,組合成一個Tuple2,作爲新RDD的元素
return v1+v2;
}
}).foreach(new VoidFunction<Tuple2<String, Integer>>() {
@Override
public void call(Tuple2<String, Integer> s) throws Exception {
System.out.println(s._1+"==="+s._2);
}
});
sortByKey講解
// 對scores RDD執行sortByKey算子
// sortByKey其實就是根據key進行排序,可以手動指定升序,或者降序
// 返回的,還是JavaPairRDD,其中的元素內容,都是和原始的RDD一模一樣的
// 但是就是RDD中的元素的順序,不同了
//sorces 是PairRDD。我們需要先將key和value互換,在排序以後z,排序以後在將key value互換。
sorces.mapToPair(new PairFunction<Tuple2<String,Integer>, Integer, String>() {
@Override
public Tuple2<Integer, String> call(Tuple2<String, Integer> t) throws Exception {
return Tuple2.apply(t._2,t._1);
}
}).sortByKey(false,1).mapToPair(new PairFunction<Tuple2<Integer,String>, String, Integer>() {
@Override
public Tuple2<String, Integer> call(Tuple2<Integer, String> t) throws Exception {
return Tuple2.apply(t._2,t._1);
}
}).foreach(new VoidFunction<Tuple2<String, Integer>>() {
@Override
public void call(Tuple2<String, Integer> s) throws Exception {
System.out.println(s._1+"==="+s._2);
}
});
join講解
List<Tuple2<Integer,String>> student=Arrays.asList(new Tuple2<Integer, String>(1,"xlucas1"),
new Tuple2<Integer, String>(2,"xlucas2"),
new Tuple2<Integer, String>(3,"xlucas3"));
List<Tuple2<Integer,Integer>> scorea=Arrays.asList(
new Tuple2<Integer, Integer>(1,90),
new Tuple2<Integer, Integer>(2,80),
new Tuple2<Integer, Integer>(3,100),
new Tuple2<Integer, Integer>(1,100)
);
JavaPairRDD<Integer,String> s1=sc.parallelizePairs(student);
JavaPairRDD<Integer,Integer> s2=sc.parallelizePairs(scorea);
// 使用join算子關聯兩個RDD
// join以後,還是會根據key進行join,並返回JavaPairRDD
// 但是JavaPairRDD的第一個泛型類型,之前兩個JavaPairRDD的key的類型,因爲是通過key進行join的
// 第二個泛型類型,是Tuple2<v1, v2>的類型,Tuple2的兩個泛型分別爲原始RDD的value的類型
// join,就返回的RDD的每一個元素,就是通過key join上的一個pair
// 什麼意思呢?比如有(1, 1) (1, 2) (1, 3)的一個RDD
// 還有一個(1, 4) (2, 1) (2, 2)的一個RDD
// join以後,實際上會得到(1 (1, 4)) (1, (2, 4)) (1, (3, 4))
s1.join(s2).foreach(new VoidFunction<Tuple2<Integer, Tuple2<String, Integer>>>() {
@Override
public void call(Tuple2<Integer, Tuple2<String, Integer>> t) throws Exception {
System.out.println("id="+t._1);
System.out.println("name="+t._2._1);
System.out.println("id="+t._2._2);
}
});
cogroup講解
// cogroup與join不同
// 相當於是,一個key join上的所有value,都給放到一個Iterable裏面去了
s1.cogroup(s2).foreach(new VoidFunction<Tuple2<Integer, Tuple2<Iterable<String>, Iterable<Integer>>>>() {
@Override
public void call(Tuple2<Integer, Tuple2<Iterable<String>, Iterable<Integer>>> t) throws Exception {
System.out.println("id="+t._1);
System.out.println("name="+t._2._1);
System.out.println("id="+t._2._2);
}
});