假设我有Queue<String>
并且我想清空队列的当前内容并对每个元素执行某些操作。使用循环我可以做类似的事情:
while (true) {
String element = queue.poll();
if (element == null) {
return;
}
System.out.println(element);
}
这感觉有点难看。我能用溪流做得更好吗?
请注意,可能有其他线程同时访问队列,因此依赖队列的大小来了解要轮询的项目数量容易出错。
答案 0 :(得分:2)
由于您询问了“ without blocking ”,因此您似乎指的是BlockingQueue
。在这种情况下,建议避免重复调用poll()
。
相反,将所有待处理元素一次性转移到本地集合,然后处理它们:
List<String> tmp = new ArrayList<>();
queue.drainTo(tmp);
tmp.forEach(System.out::println);
您还可以避免多次System.out
(隐式)同步:
List<String> tmp=new ArrayList<>();
queue.drainTo(tmp);
System.out.println(tmp.stream().collect(Collectors.joining(System.lineSeparator())));
或
List<String> tmp=new ArrayList<>();
queue.drainTo(tmp);
System.out.println(String.join(System.lineSeparator(), tmp));
(虽然这不支持流操作)...
答案 1 :(得分:1)
根据我的理解,如果你想使用流,那么你就不能修改你正在进行操作的同一个集合。
下面的代码可能会对您有所帮助:
string stdalph = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
string ourkey = "xMK6JDC18hLoYeEkBSlIyVO0niadRf9qH5N4tbWpZ3wgAuc7GQjXm2FUvTzPrs";
StringBuilder sbalph = new StringBuilder(stdalph);
StringBuilder sbkey = new StringBuilder(ourkey);
textBox2.Text = textBox1.Text;
答案 2 :(得分:0)
您不需要使用流来减少代码的丑陋(流解决方案可能会更难看)。
String s = null;
while((s = queue.poll()) != null)
System.out.println(s);
答案 3 :(得分:0)
目前我能想出的最佳答案如下:
StreamEx.generate(() -> queue.poll())
.takeWhile(Objects::nonNull)
.forEach(System.out::println);
但是它使用了一个库(StreamEx)。我们可以用vanilla Java做到这一点吗?
答案 4 :(得分:0)
我认为你不想要并发症,但如果我错了,你可以这样做:
Spliterator<String> spliterator = new Spliterators.AbstractSpliterator<String>(queue.size(), 0) {
@Override
public boolean tryAdvance(Consumer<? super String> action) {
String element = queue.poll();
if (element == null) {
return false;
} else {
action.accept(element);
return true;
}
}
};
StreamSupport.stream(spliterator, false).forEach(System.out::println);
您可以查看Spliterators
和StreamSupport
的文档,了解各种可能的改进。