簡體   English   中英

當方法引用用作 KeyBy 的輸入參數時,lambda 和雙冒號有何不同?

[英]How do lambda and double colons differ when method references are used as input parameters to KeyBy?

Flink 版本為 1.10.0

代碼如下:

public class WorkerOnlineStatusRun {
  private static String datahubEndpoint = GlobalParameter.getPublicEndpoint();
  private static String redisServer = GlobalParameter.getRedisServer();
  private static long datahubStartInMs;


  public static void main(String[] args) throws Exception {
    if (args.length != 0) {
      if (args[0] == null) {
        datahubStartInMs = GlobalParameter.getDatahubStartInMs();
      } else {
        datahubStartInMs =
            TimeUtils.convertLocalDateTimeStr2Long(args[0]); // ""2022-05-26T08:55:00.000"
      }
    }


    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();


    // checkpoint every 10 min
    env.getCheckpointConfig().setCheckpointInterval(1_000L * 60 * 10);


    // use event time for the application
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);


    // env.setParallelism(1);


    env.getConfig().setAutoWatermarkInterval(GlobalParameter.getWatermarkInterval());


    long currTS = System.currentTimeMillis();


    KeyedStream<WorkSign, Object> workStatus =
        env.fromElements(
                new WorkSign("worker_id1", currTS, WorkTimestampFlagType.STARTWORK),
                new WorkSign(
                    "worker_id1", currTS + 1_000L * 60 * 20, WorkTimestampFlagType.STOPWORK))
            .uid("worksign")
            .returns(new TypeHint<WorkSign>() {})
            .keyBy(r -> r.getWorker_uniqe_id()); // this wrong


    DatahubSourceTrace.getSingleOutputStreamOperatorWorker(env, datahubEndpoint, datahubStartInMs)
        .uid("worker")
        .returns(new TypeHint<Worker>() {})
        .keyBy(r -> r.getWorker_uniqe_id())
        .connect(workStatus)
        .process(new checkWorkerOnlineStatusFunction());


    env.execute();
  }
}

以下錯誤是:

Exception in thread "main" java.lang.UnsupportedOperationException: Key types if input KeyedStreams don't match: String and GenericType<java.lang.Object>.
    at org.apache.flink.streaming.api.datastream.ConnectedStreams.transform(ConnectedStreams.java:366)
    at org.apache.flink.streaming.api.datastream.ConnectedStreams.process(ConnectedStreams.java:339)
    at org.apache.flink.streaming.api.datastream.ConnectedStreams.process(ConnectedStreams.java:307)
    at com.kursk.WorkerOnlineStatusRun.main(WorkerOnlineStatusRun.java:60)

但是如果 lambda 表達式是通過用雙冒號替換它來編寫的

public class WorkerOnlineStatusRun {
  private static String datahubEndpoint = GlobalParameter.getPublicEndpoint();
  private static String redisServer = GlobalParameter.getRedisServer();
  private static long datahubStartInMs;

  public static void main(String[] args) throws Exception {
    if (args.length != 0) {
      if (args[0] == null) {
        datahubStartInMs = GlobalParameter.getDatahubStartInMs();
      } else {
        datahubStartInMs =
            TimeUtils.convertLocalDateTimeStr2Long(args[0]); // ""2022-05-26T08:55:00.000"
      }
    }

    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

    // checkpoint every 10 min
    env.getCheckpointConfig().setCheckpointInterval(1_000L * 60 * 10);

    // use event time for the application
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

    // env.setParallelism(1);

    env.getConfig().setAutoWatermarkInterval(GlobalParameter.getWatermarkInterval());

    long currTS = System.currentTimeMillis();

    KeyedStream<WorkSign, Object> workStatus =
        env.fromElements(
                new WorkSign("worker_id1", currTS, WorkTimestampFlagType.STARTWORK),
                new WorkSign(
                    "worker_id1", currTS + 1_000L * 60 * 20, WorkTimestampFlagType.STOPWORK))
            .uid("worksign")
            .returns(new TypeHint<WorkSign>() {})
            .keyBy(WorkSign::getWorker_uniqe_id);  // modify only here ,replace with ClassName:instanceMethodName

    DatahubSourceTrace.getSingleOutputStreamOperatorWorker(env, datahubEndpoint, datahubStartInMs)
        .uid("worker")
        .returns(new TypeHint<Worker>() {})
        .keyBy(r -> r.getWorker_uniqe_id())
        .connect(workStatus)
        .process(new checkWorkerOnlineStatusFunction());

    env.execute();
  }
}

它工作正常!

當然,這個 getWorker_uniqe_id 返回一個 String 類型,但這仍然不能解釋為什么 lambda 表達式不起作用?

public String getWorker_uniqe_id() {
    return worker_uniqe_id;
}

我google java mehtod參考,沒有提到lamdba效果和雙冒號的區別,誰能告訴我這個錯誤的原因是什么

o,我可能已經找到了我的問題的答案

問題應該是隱式類型轉換,這段代碼

KeyedStream<WorkSign, Object> workStatus.....

在 lambda 中不進行類型轉換,而雙冒號具有隱式類型轉換

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM