[英]Java - Basic streams usage of forEach
我有一个叫做Data
的类,它只有一个方法:
public boolean isValid()
我有一个Data
List
,我想通过Java 8流遍历它们。 我需要计算此List
有多少valid
Data
对象,并仅打印出valid
条目。
下面是我走了多远,但我不知道如何。
List<Data> ar = new ArrayList<>();
...
// ar is now full of Data objects.
...
int count = ar.stream()
.filter(Data::isValid)
.forEach(System.out::println)
.count(); // Compiler error, forEach() does not return type stream.
我的第二次尝试:(可怕的代码)
List<Data> ar = new ArrayList<>();
...
// Must be final or compiler error will happen via inner class.
final AtomicInteger counter = new AtomicInteger();
ar.stream()
.filter(Data:isValid)
.forEach(d ->
{
System.out.println(d);
counter.incrementAndGet();
};
System.out.printf("There are %d/%d valid Data objects.%n", counter.get(), ar.size());
如果以后不需要包含有效和无效对象的原始ArrayList
,则可以简单地执行Collection操作而不是Stream操作:
ar.removeIf(d -> !d.isValid());
ar.forEach(System.out::println);
int count = ar.size();
否则,您可以像
List<Data> valid = ar.stream().filter(Data::isValid).collect(Collectors.toList());
valid.forEach(System.out::println);
int count = valid.size();
为您需要多次存储的东西还不错。 如果列表确实很大,则可以使用以下方法(通常)将存储内存减少32倍:
BitSet valid = IntStream.range(0, ar.size())
.filter(index -> ar.get(index).isValid())
.collect(BitSet::new, BitSet::set, BitSet::or);
valid.stream().mapToObj(ar::get).forEach(System.out::println);
int count = valid.cardinality();
当然,您当然也可以使用
int count = 0;
for(Data d: ar) {
if(d.isValid()) {
System.out.println(d);
count++;
}
}
Peek与foreach相似,不同之处在于它使您可以继续播放流。
ar.stream().filter(Data::isValid)
.peek(System.out::println)
.count();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.