繁体   English   中英

Java-forEach的基本流用法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM