scala 二次排序

  • 1.需求

    要求根据用户不同的学习时长来进行排序。

优先根据学习时长排序,如果学习1时长相等,在根据学习2时长进行排序

数据格式:

    模拟数据:分别为时间戳-用户id--学习1时长--学习2时长

1519908784338	aa	7	5
1519906384338	aa	8	9
1519908544338	bb	36	1
1519908244338	aa	2	1
1519910824338	cc	34	38
1519911304338	cc	6	9
1519908064338	aa	10	7
1519909564338	aa	10	0
1519907164338	aa	3	6
1519905904339	bb	40	9
  • 2.代码实现

    代码实现思路:

  • 2.1.先将数据转换成 (id,(time,first,second))的类型格式
  • 2.2.通过reduceByKey 对数据进行聚合,取最小时间,first数据的总和,second数据的总和
  • 2.3.通过LogSortKey中做二次排序的判断。
  • 2.4.通过sortByKey 对数据进行排序
package spark_case
import org.apache.spark.{SparkConf, SparkContext}
/**
  * 优先第一种数据排序,如果相等,在根据第二种数据进行排序
  */
object LogCase {
  def main(args: Array[String]): Unit = {
    //配置信息类
    val conf=new SparkConf().setAppName("logSS").setMaster("local")
    //上下文对象
    val sc:SparkContext= new SparkContext(conf)
    val records= sc.textFile("/home/wxp/files/case/test.log")
    val data=records.map{l=>
      val array=l.split("\t")
      val pair = Array(array(0).toLong,array(2).toLong,array(3).toLong)
      (array(1).toString,pair)
      }
    println(data.first())
    //聚合操作,根据id ,计算总量 ,时间P
    val map=data.reduceByKey{(x,y)=>
      if(y(0)<x(0)) y(0) else x(0)
      y(2)=x(2)+y(2)
      y(1)=x(1)+y(1)
      y
    }
    val mapWithSortKey = map.map{ line=>
      val key=new LogSortKey(line._2(1),line._2(2))
      println(line._1+"--"+line._2.toBuffer+"--"+key)
      (key,line._1)
    }
    val sorted=mapWithSortKey.sortByKey(false)
    val result=sorted.map(item=>item._2)
    result.collect().foreach(println)
  }
}

运行上面代码就可以看到结果了

------------------------------ 下面 辅助类 或 法--------------------- ----------------- 

 LogSortKey:辅助,做二次排序的判断。

package spark_case
class LogSortKey(val first:Long,val second:Long) extends Ordered[AppvisitLogSortKey] with Serializable{
  override def compare(that: AppvisitLogSortKey): Int = {
    // 按第一列数据排序,如果第一列数据相等,按第二列数据进行排序
    if(this.first > that.first || (this.first == that.first && this.second > that.second))
    {
     return 1
    }else if(this.first < that.first || (this.first == that.first && this.second < that.second)) {
     return -1
    }else{
    return  0
    }
  }
}
  • 3.模拟数据 log 生成类(JAVA编写)
package test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.*;

public class GenerateLog {
    public static void main(String[] args) {
        GenerateTestLog();
    }
   private static void GenerateTestLog(){
    List<String> userIds=new ArrayList<String>();
    userIds.add("aa");
    userIds.add("bb");
    userIds.add("cc");
    Random random =new Random();
    StringBuffer buffer=new StringBuffer("");
    for (int i = 0; i <10 ; i++) {
        Calendar cal=Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.MINUTE,random.nextInt(100));
        long timeStamp=cal.getTime().getTime();
        String userId=userIds.get(random.nextInt(3));
        long first=random.nextInt(10);
        long second=random.nextInt(10);
        buffer.append(timeStamp).append("\t")
                .append(userId).append("\t")
                .append(first).append("\t")
                .append(second).append("\n");
    }
    PrintWriter pw=null;
    try {
        pw=new PrintWriter(new OutputStreamWriter(new FileOutputStream("/home/wxp/files/case/test.log")));
        pw.write(buffer.toString());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }finally {
        pw.close();
    }

 

转载于:https://my.oschina.net/wxp3967/blog/1627510

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值