【问题标题】:What is the idiomatic way to exhaust a Queue in Java 8?在 Java 8 中耗尽队列的惯用方法是什么?
【发布时间】:2018-06-04 07:37:55
【问题描述】:

假设我有一个队列,我想用尽它。我会这样做的方式类似于

void emptyQueue(Queue<T> q) {
  T i;
  while ((i = q.poll()) != null)
    consume(i);
}

但这感觉像是一种古老的方法。

我想要更像forEach 方法的东西。当然,它是存在的 - QueueCollection - 但它迭代元素,而不是消耗它们。

理想情况下,我希望在 Queue 上使用 pollEach 方法 - 但我似乎找不到任何合适的方法。

这种代码你是怎么写的?

【问题讨论】:

  • 您确实将消费者添加到forEach...q.forEach(this::consume); 应该等同于您的代码。
  • @daniu 不会在元素被消耗时从队列中删除。
  • 您可以将while 更改为:for(T ti= null; (i = queue.poll()) != null; ){...},这可能会更好一些,因为i 变量仅在for 范围内可用
  • 如果您的队列继承自AbstractQueue,您可以简单地使用clear() 方法。

标签: java java-8 queue


【解决方案1】:

您可以使用自己的生成器在队列中调用poll()

Stream.generate( () -> q.poll() )
    .takeWhile(Objects::nonNull) //Note that this is only available in java 9
    .forEach(i -> consume(i));

此方法也是控制通过流的内容的示例。您可以管理诸如阻塞之类的事情。本例中的takeWhile 步骤仅显示如何检测数据的结尾。

【讨论】:

  • 我非常喜欢这个解决方案,您可以将() -&gt; q.poll() 缩短为q::poll,也可以将i -&gt; consume(i) 缩短为this::consume(假设consume 是一个类的实例成员`)
  • 请注意,Stream.generate 创建了一个 unordered 流,因此从语义上讲,这不是一个正确的解决方案(或至少与原始代码不同),即使它碰巧在顺序执行中以正确的顺序处理元素。无论如何,它对“过时”循环没有任何优势……
猜你喜欢
  • 2023-04-09
  • 2022-01-21
  • 2020-08-08
  • 1970-01-01
  • 2013-09-27
  • 2011-06-20
  • 2022-01-08
  • 2010-10-05
  • 2010-10-27
相关资源
最近更新 更多