模仿 Java 8 中的 C# 操作

Mimic C# Actions in Java 8

Actions 很好,因为你可以传递一个返回 void 作为参数的任意函数。

用例?任何函数包装器,例如 Timers.

所以基本上在 C# 中我可以写一个方法

private static void Measure(Action block) {
    var watch = new Stopwatch();
    watch.Start();
    block();
    watch.Stop();
    Console.WriteLine(watch.ElapsedMilliseconds);
}

并像

一样使用它
public static void Main(string[] args) {
    Measure(() => {Console.WriteLine("Hello");});
}

测量该方法所用的时间。挺整洁的。现在,如果我想在 Java 中模仿它,我需要编写一个方法

private static <T> Consumer<T> measure(Consumer<T> block) {
        return t -> {
            long start = System.nanoTime();
            block.accept(t);
            System.out.printf("Time elapsed: %d Milliseconds\n", (System.nanoTime() - start) / 1000);
        };
    }

并像

一样使用它
public static void main(String[] args) {
    measure(Void -> System.out.println("Hello")).accept(null);
}

问题

  1. 消费者期望只有一个参数,而 Actions 可以是 returns 无效的任何内容。
  2. 由于我不能简单地在 Java 中调用 block(),我需要向它传递一个冗余的 null 参数。
  3. 由于后一个原因,我必须让 measure() 本身返回一个 Consumer。

问题: - 我可以通过使用方法而不是外部消费者来模仿它,从而使 null 参数过时吗?

对于无参数方法,您可以使用 Runnable 而不是 Consumer

private static Runnable measure(Runnable block) {
    return () -> {
        long start = System.nanoTime();
        block.run();
        System.out.printf("Time elapsed: %d Milliseconds\n", (System.nanoTime() - start) / 1000);
    };
}

然后:

public static void main(String[] args) {
    measure(System.out::println("Hello")).run();
}

不过,现在想想,你真的不需要 return Runnable:

private static void measure(Runnable block) {
        long start = System.nanoTime();
        block.run();
        System.out.printf("Time elapsed: %d Milliseconds\n", (System.nanoTime() - start) / 1000);
}