关于Java:stream.forEach中的多行代码

multiple lines of code in stream.forEach

我具有以下用于读取文件行的??代码:

1
2
3
4
5
6
7
8
9
10
11
12
String fileName ="dataset/ANC-all-count.txt";
Integer i=0;
//read file into stream, try-with-resources
try (Stream<String> stream = Files.lines(Paths.get(fileName), StandardCharsets.ISO_8859_1)) {

    stream.forEach(System.out::println);
    i++;

} catch (IOException e) {
    e.printStackTrace();
}
System.out.println("count is :"+i);

但问题是我需要将i++放在以下行中:

1
stream.forEach(System.out::println);

所以我想要这样的东西:

1
stream.forEach(System.out::println; i++);

但是这种方式无法正常工作,因此任何人都可以帮助我如何使其正常工作吗?


您应该在这里问两件事:

a)如何在stream.forEach()中放置多行代码?

b)我应该怎么计算Stream中的行数?

问题b)已经被其他张贴者回答;另一方面,一般问题a)有一个完全不同的答案:

使用(可能是多行)lambda表达式或将引用传递给多行方法。

在这种特殊情况下,您可以声明i一个字段,或者使用计数器/包装对象而不是i

例如,如果要显式地在forEach()中包含多行,则可以使用

1
2
3
4
5
class Counter { // wrapper class
    private int count;
    public int getCount() { return count; }
    public void increaseCount() { count++; }
}

然后

1
2
3
4
5
Counter counter = new Counter();
lines.stream().forEach( e -> {
    System.out.println(e);
    counter.increaseCounter(); // or i++; if you decided i is worth being a field
} );

另一种方法,这次将这些多行隐藏在方法中:

1
2
3
4
5
6
7
8
class Counter { // wrapper class
    private int count;
    public int getCount() { return count; }
    public void increaseCount( Object o ) {
        System.out.println(o);
        count++;
    }
}

然后

1
2
Counter counter = new Counter();
lines.stream().forEach( counter::increaseCount );

甚至

1
2
Counter counter = new Counter();
lines.stream().forEach( e -> counter.increaseCount(e) );

如果您需要具有多个参数的使用者,第二种语法会派上用场;第一种语法仍然是最短和最简单的。


forEach方法采用实现Consumer的任何类的实例。因此,这是一个使用自定义Consumer实现的示例,该实现与计数保持一致。稍后,您可以在Consumer实现上调用getCount()以获得计数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerDemo {
    public static void main(String[] args) {
        List<String> lines = new ArrayList<String>();
        lines.add("line 1");
        lines.add("line 2");

        MyConsumer countingConsumer = new MyConsumer();
        lines.stream().forEach(countingConsumer);
        System.out.println("Count:" + countingConsumer.getCount());
    }

    private static class MyConsumer implements Consumer<String> {
        private int count;

        @Override
        public void accept(String t) {
            System.out.println(t);
            count++;
        }

        public int getCount() {
            return count;
        }
    }
}


使用peek()count()

1
2
i = (int) stream.peek(System.out::println)
                .count();