在字符串上应用JDK 8 Consumer

Mac*_*arz 12 java lambda java-8

我有一个关于Java 8的问题.这是我的源代码:

final Consumer<String> d = e -> System.out.println(e);
final Function<String, String> upper = x -> x.toUpperCase();
final Function<String, String> lower = x -> x.toLowerCase();

new Thread(() -> d.accept(upper.apply("hello 1"))).run();
new Thread(() -> d.accept(lower.apply("hello 2"))).run();
Run Code Online (Sandbox Code Playgroud)

这非常有效并产生以下输出:

HELLO 1
hello 2
Run Code Online (Sandbox Code Playgroud)

我的问题是,现在如果以上语法d.acceptupper.apply是唯一可能的一个或如果有一些比较"的Java 8拉姆达"的风格,我们可以写的最后两行.

Hol*_*ger 9

在谈到有关lambda表达式或功能接口的任何内容之前,我们必须讨论你真正有问题的错误:你正在调用 run() 一个线程!如果你想开始一个新的线程,你必须调用start()Thread来说,如果你想运行的代码顺序,不创建一个Thread(只是一个Runnable).

也就是说,defaultJava 8的功能接口上有一些用于组合功能的方法,例如你可以链接两个Functions,Function.andThen(…)但是可用的组合远远没有完成.

如果您的应用程序中重复某个组合任务,您可以考虑创建实用程序方法:

public static <T> Runnable bind(T value, Consumer<T> c) {
    return ()->c.accept(value);
}
public static <T,U> Consumer<U> compose(Function<U,T> f, Consumer<? super T> c) {
    return u->c.accept(f.apply(u));
}
Run Code Online (Sandbox Code Playgroud)

 

new Thread(bind("Hello 1", compose(upper, d))).start();
new Thread(bind("Hello 2", compose(lower, d))).start();
Run Code Online (Sandbox Code Playgroud)

但这三个部分看起来更像是流API的任务:

Stream.of("Hello 1").map(upper).forEach(d);
Stream.of("Hello 2").map(lower).forEach(d);
Run Code Online (Sandbox Code Playgroud)

我在这里留下了新线程的创建,因为它无论如何都没有任何好处.

如果您真的想要并行处理,可以按字符进行:

"Hello 1".chars().parallel()
  .map(Character::toUpperCase).forEachOrdered(c->System.out.print((char)c));
Run Code Online (Sandbox Code Playgroud)

但鉴于任务的简单性和并行处理的固定开销,仍然没有任何好处.

  • @Tagir Valeev:我知道,但我不想深入细节.毕竟,即使Java 9具有更好的分离支持,这个问题的任务也不会受益于并行执行.我怀疑是否有一个`String`足够长,以至于一个简单的`toUpperCase`转换可以从并行执行中受益.顺便说一句,Java 8 API有办法克服这个限制:使用`CharBuffer.wrap(string).chars()`而不是`string.chars()`... (2认同)

sak*_*029 5

您也可以这样写:

    new Thread(() -> Stream.of("hello 1").map(upper).forEach(d)).run();
    new Thread(() -> Stream.of("hello 1").map(lower).forEach(d)).run();
Run Code Online (Sandbox Code Playgroud)

或更直接的:

    new Thread(() -> Stream.of("hello 1").map(String::toUpperCase).forEach(System.out::println)).run();
    new Thread(() -> Stream.of("hello 1").map(String::toLowerCase).forEach(System.out::println)).run();
Run Code Online (Sandbox Code Playgroud)