sortBy函数
sortBy
函数是在org.apache.spark.rdd.RDD
类中实现的。
该函数有三个参数:
第一个参数是一个函数,该函数的也有一个带T泛型的参数,返回类型和RDD中元素的类型是一致的;
第二个参数是ascending
,从字面的意思大家应该可以猜到,这参数决定排序后RDD中的元素是升序还是降序,默认是true,也就是升序;
第三个参数是numPartitions
,该参数决定排序后的RDD的分区个数,默认排序后的分区个数和排序之前的个数相等。
从sortBy
函数的实现可以看出,第一个参数是必须传入的,而后面的两个参数可以不传入。而且sortBy
函数函数的实现依赖于sortByKey
函数。
案例
scala写
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
object Top_SortBy {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setMaster("local")
.setAppName("Top_SortBy")
val sc = new SparkContext(conf)
val lines: RDD[String] = sc.textFile("D:\\eclipse\\wc\\scalaworid\\top.txt")
val ints: Array[Int] = lines.map(Integer.parseInt(_)).sortBy((e:Int) => e,false,1).take(3)
for (a <- ints){
println(a)
}
//结果:
//9
//7
//6
}
}
java写
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import java.util.List;
public class SortBya {
public static void main(String[] args) {
SparkConf conf = new SparkConf()
.setAppName("SortBy")
.setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> textFile = sc.textFile("D:\\eclipse\\wc\\scalaworid\\top.txt");
//将一列String类型的数据转换成int
JavaRDD<Integer> map = textFile.map(new Function<String, Integer>() {
@Override
public Integer call(String s) throws Exception {
return Integer.parseInt(s);
}
});
//用sortBy进行排序三个参数(new Function,升序或降序,分区)
JavaRDD<Integer> sortBy = map.sortBy(new Function<Integer, Integer>() {
@Override
public Integer call(Integer integer) throws Exception {
return integer;
}
}, false, 3);
//用take算子取前几个
List<Integer> take = sortBy.take(3);
for (Integer e : take) {
System.out.println(e);
}
//结果
//9
//7
//6
}
}
sortByKey函数
sortByKey
函数作用于Key-Value
形式的RDD,并对Key
进行排序。它是在org.apache.spark.rdd.OrderedRDDFunctions
中实现的。
和sortBy一样,该函数返回的RDD一定是ShuffledRDD
类型的,因为对源RDD进行排序,必须进行Shuffle
操作,而Shuffle
操作的结果RDD就是ShuffledRDD
。里面用到了RangePartitioner
,它可以使得相应的范围Key数据分到同一个partition
中,然后内部用到了mapPartitions
对每个partition
中的数据进行排序,而每个partition
中数据的排序用到了标准的sort
机制,避免了大量数据的shuffle。
案例
scala写
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
object Top_SortByKeta {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setAppName("Top_SortByKey")
.setMaster("local")
val sc = new SparkContext(conf)
val lines: RDD[String] = sc.textFile("D:\\eclipse\\wc\\scalaworid\\top.txt")
val strings: Array[String] = lines.map((_,1)).sortByKey(false,1).map(_._1).take(3)
for (e <- strings){
println(e)
}
//结果:
// 9
//7
//6
}
}
java写
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.Function;
import org.apache.spark.api.java.function.PairFunction;
import scala.Tuple2;
import java.util.List;
public class SortByKeya {
public static void main(String[] args) {
SparkConf conf = new SparkConf()
.setMaster("local")
.setAppName("SortByKey");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> textFile = sc.textFile("D:\\eclipse\\wc\\scalaworid\\top.txt");
//将一列String类型数据转换成Tuple2(Integer,Integer)例如(源数据,1)...
JavaPairRDD<Integer, Integer> pairRDD = textFile.mapToPair(new PairFunction<String, Integer, Integer>() {
@Override
public Tuple2<Integer, Integer> call(String s) throws Exception {
return new Tuple2<>(Integer.parseInt(s),1);
}
});
//用sortByKey排序,取元组的第一个值
JavaPairRDD<Integer, Integer> sortByKey = pairRDD.sortByKey(false);
JavaRDD<Integer> map = sortByKey.map(new Function<Tuple2<Integer, Integer>, Integer>() {
@Override
public Integer call(Tuple2<Integer, Integer> tuple2) throws Exception {
return tuple2._1;
}
});
//用take算子取前三
List<Integer> take = map.take(3);
for (Integer a:take) {
System.out.println(a);
}
//结果:
// 9
//7
//6
}
}