gpt4 book ai didi

java - 一个 Action 的多个 Java 消费者

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:32:44 24 4
gpt4 key购买 nike

有没有办法让下面的 Action 实际上是两个 Action 合二为一?

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<? super String> action我通常将其指定为 log::debug或像 AtomicReference::set 这样的自定义函数但是,如果我想成为两者或第三者怎么办?我怎样才能让 Action 执行一些独立的 Action ?

我知道我可以创建自定义 Consumer那做任何我想做的事,但我认为这会很方便 如果我几乎可以像对待 nvarargs 一样对待这个 Action ,但对于函数/ Action 。

最佳答案

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

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

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

哪里都是action?被声明为 Consumer<X>Consumer<? super X> .

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

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

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

不看文档我敢打赌:

  • 你需要实际调用一个最终的消费行为,比如forEach (或 countempty 等)以便执行不同的查看。
  • 执行顺序的唯一限制是只要 i < j,对于流中的任何给定元素,action-i 将在 action-j 之前执行。除非我们知道关于流的其他信息(它是并行/串行、排序等),否则不能做出其他假设。

我想你可能想使用 Consumer.andThen但是根据你的问题内容peek如果某些 Action 的执行不是手头任务的核心/主要,而是一个理想的副作用,那么这似乎是一个合理的解决方案。

也许你想传递一个修改过的流,它会“监视”流引用被传递到的代码稍后正在处理的对象。在那种情况下 peek即使不是唯一的选择,也是更好的选择。

当然,您也可以将两者结合起来。

关于java - 一个 Action 的多个 Java 消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50593918/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com