使用java编写spark UDF

1、背景

 最近对接一些数据,其中有一个日期字段的数据是这样的 26/04/201711:11:17 我需要把它转成正常的YYYY-MM-dd HH:mm:ss的格式,由于文件都在hdfs上,所以只有写spark的udf函数来处理,以前处理spark,都是撸scala,但是最近这个项目主要用java,处理数据只是一个很小的部分,所以打算用java来搞定,因此决定研究下java写spark的udf

spark 版本 2.4.3

scala代码
package org
import java.text.SimpleDateFormat
import org.apache.spark.sql.{DataFrame, SparkSession}
import org.apache.spark.sql.functions._

object SparkParseCSV {
  def main(args: Array[String]): Unit = {

    val spark = SparkSession.builder()
      .appName("ParseCSV")
      .master("local[2]")
      .config("spark.executor.cores", "1")
      .config("spark.executor.memory", "1G")
      .config("hive.metastore.uris", "thrift://hadoop103:9083")
      .enableHiveSupport()
      .getOrCreate()

    import spark.implicits._
    
	val parseToTimestamp=udf((dstring:String)=>{

      val sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

      val sf1 = new SimpleDateFormat("dd/MM/yyyyHH:mm:ss")

      val res=sf.format(sf1.parse(dstring))

      res
    })
    
	val df = spark.read.format("csv")
      .option("header","true")
      .load("hdfs://mycluster/test/input/Dataset-Unicauca-Version2-87Atts_test.csv")
      .withColumn(
        "datetime",parseToTimestamp(col("Timestamp"))
      )

    df.show()

    spark.close()
  }
}

java代码

A、思路

//查了下网上的一下相关文章,很多都是使用spark提供的java api 的UDF来重写里面的方法,
//然后再注册方法使用
import org.apache.spark.sql.api.java.UDF1;
spark.udf().register("twoDecimal", new UDF1<Double, Double>() {
         @Override
         public Double call(Double in) throws Exception {
             BigDecimal b = new BigDecimal(in);
             double res = b.setScale(2,BigDecimal.ROUND_HALF_DOWN).doubleValue();
             return res;
         }

但是我用这种方法没有成功,最后开了下源码,仿照着写了下,register需要三个参数
1、函数名
2、函数体
3、返回类型

在这里插入图片描述

B、实现

/*
register需要三个参数
1、函数名
2、函数体
3、返回类型
*/
spark.udf().register("parseToTimestamp",(String dstring)->{

            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            SimpleDateFormat sf1 = new SimpleDateFormat("dd/MM/yyyyHH:mm:ss");

            String res=sf.format(sf1.parse(dstring));

            return res;
        }, DataTypes.StringType);
 //在sparksql中,直接使用函数即可
 spark.sql("select parseToTimestamp('26/04/201711:11:11'");
 //在dsl中,需要使用callUDF调用函数
 Dataset df = spark.read.format("csv")
      .option("header","true")
      .load("hdfs://mycluster/test/input/Dataset-Unicauca-Version2-87Atts_test.csv")
      .withColumn(
        "datetime",callUDF("parseToTimestamp",col("Timestamp"))
      );
    df.show()
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值