【问题标题】:Multiple Java Consumers for an Action一个动作的多个 Java 使用者
【发布时间】:2018-05-29 22:33:16
【问题描述】:

有没有办法让以下动作实际上是两个动作合二为一?

static int process(String[] cmd, File dir, Consumer<? super String> action) throws IOException {
    ProcessBuilder pb = new ProcessBuilder(cmd);
    pb.directory(dir);
    pb.redirectErrorStream(true);
    Stopwatch sw = Stopwatch.createStarted();
    Process p = pb.start();
    int exit = -1;
    try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
        br.lines().forEach(action);
    } finally {
        log.debug("Ending process {} with exist code {} in time {}", pb.command(),
                exit = p.destroyForcibly().exitValue(), sw);
    }
    return exit;
}

所以Consumer&lt;? super String&gt; action 我通常将其指定为log::debug 或像AtomicReference::set 这样的自定义函数,但是如果我想要两者兼而有之,或者第三个呢?如何让操作执行一些独立的操作?

我知道我可以创建一个自定义的 Consumer 来做我想做的任何事情,但我认为这会非常方便 如果我几乎可以将操作视为 nvarargs 等价物,但对于功能/操作。

【问题讨论】:

    标签: java function lambda java-8 consumer


    【解决方案1】:

    这里有一些替代方案,其中一些已经被其他人提到过。

    也许最类似于 lambda 的方法是使用消费者自己的聚合方法 andThen(在 Consumer 本身中定义):

    Stream<X> exes = ....
    exes.forEach(action1
        .andThen(action2)
        .andThen(action3)
        .andThen(...)
        .andThen(actionN));
    

    所有action? 都声明为Consumer&lt;X&gt;Consumer&lt;? super X&gt;

    无需查看文档即可确认。我猜想对于流中的每个元素,动作 1 到 N 在同一个线程上一个接一个地执行。

    这里的另一种可能性是使用peek,它基本上将流的元素传递给一个动作而不消耗它们,因为它返回一个包含相同元素的流。

    Stream<X> exes = ...
    exes.peek(action1)
     .peek(action2)
     .peek(action3)
     .peek(...)
     .forEach(actionN);
    

    没有看文档,我敢打赌:

    • 您需要实际调用最终消耗操作,如forEach(或countempty 等),以便执行不同的窥视。
    • 执行顺序的唯一限制是只要 i

    我认为您可能希望根据您的问题内容使用Consumer.andThen,但是如果有一些动作的执行不是手头任务的中心/主要,而是像一个理想的副作用。

    也许您想传递一个修改过的流,该流将“窥探”流引用已传递到的代码稍后正在处理哪些对象。在这种情况下,peek 是更好的选择,如果不是唯一的选择。

    当然你也可以两者结合。

    【讨论】:

      【解决方案2】:

      创建一个代表其他消费者的Consumer 很容易。你就写

       str -> {
         action1(str);
         action2(str);
         // etc
       }
      

      由于您没有 使用方法引用,因此您始终可以使用 lambda。以这种风格编写 Consumer 也往往比尝试以其他方式组合它们更具可读性,尽管其他方式也是可能的。

      【讨论】:

        猜你喜欢
        • 2019-05-03
        • 2018-06-02
        • 2018-06-12
        • 1970-01-01
        • 2011-08-24
        • 2018-04-10
        • 1970-01-01
        • 1970-01-01
        • 2013-12-03
        相关资源
        最近更新 更多