#java #bufferedreader #java-11
#java #bufferedreader #java-11
Вопрос:
Я пытаюсь получить количество строк, которые были обработаны лямбда-символом, перебирающим строки в BufferedReader.
Есть ли способ получить количество без записи 2-й лямбды, чтобы получить только количество строк?
final BufferedReader inReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
inReader.lines().forEach(line -> {
// do something with the line
});
Могу ли я получить количество также в приведенном выше блоке кода? Я использую Java 11.
Ответ №1:
Если я вас правильно понял, вы хотите посчитать в своем lamba. Конечно, вы можете это сделать. Просто инициализируйте count
переменную перед выполнением forEach
и увеличьте значение count
в вашем лямбда-блоке. Вот так:
final BufferedReader inReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
// fixed the long by this
final AtomicLong counter = new AtomicLong();
inReader.lines().forEach(line -> {
counter.incrementAndGet();
// do something with the line
});
// here you can do something with the count variable, like printing it out
System.out.printf("count=%d%n", counter.get());
forEach
Метод происходит от Iterable
. Это определенно не тот способ, который я бы выбрал для обработки reader. Я бы сделал что-то вроде этого:
try (BufferedReader inReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"))) {
Stream<String> lines = inReader.lines();
long i = lines.peek(line -> {
// do something with the line
}).count();
System.out.printf("count=%d%n", i);
}
PS: на самом деле я это не проверял, поэтому поправьте меня, если я допустил ошибку.
Ответ №2:
попробуйте это:
AtomicLong count = new AtomicLong();
lines.stream().forEach(line -> {
count.getAndIncrement();
// do something with line;
});
Комментарии:
1. Правильно. Потоки имеют два типа функций: терминальные и не терминальные. Нетерминальные операции возвращают поток, а терминал возвращает что-то еще. forEach является терминалом, и вы не можете вызвать count в результате, потому что это не поток. С другой стороны, peek — это нетерминальная операция, которая выполняет то же самое — применяет потребителя к потоку — но возвращает тот же steam, полученный в качестве входных данных, так что теперь вы можете вызвать count() для результата.