Как мне перечислить, отобразить и "напечатать, если число> 0" с Java 8/stream API?
Здесь мой код, как сейчас.
List<Cat> cats = petStore.getCatsForSale();
if (!cats.empty)
logger.info("Processing for cats: " + cats.size());
for (Cat cat : cats) {
cat.giveFood();
}
Мой коллега пишет действительно хороший код, используя API потока Java. Я пытался переписать это как одно потоковое утверждение, но я застрял.
petStore.getCatsForSale().stream.forEach(cat -> cat.giveFood)
.countTheCats().thenDo(logger.info("Total number of cats: " + x)); // Incorrect... is this possible?
Как я могу это сделать? В идеале я хочу одно потоковое выражение...
Ответы
Ответ 1
Я не уверен, почему вы хотите использовать потоки, поскольку текущие решения цикла работают, но вы также можете использовать Stream<List<Cat>>
:
Stream.of(petStore.getCatsForSale())
.filter(cats -> !cats.isEmpty())
.flatMap(cats -> {
logger.info("Processing for cats: " + cats.size());
return cats.stream();
})
.forEach(Cat::giveFood);
Может быть, оптимизация:
Stream.of(petStore.getCatsForSale())
.filter(cats -> !cats.isEmpty())
.peek(cats -> logger.info("Processing for cats: " + cats.size()))
.flatMap(Collection::stream)
.forEach(Cat::giveFood);
Или используйте этот другой вариант:
Stream.of(petStore.getCatsForSale())
.filter(cats -> !cats.isEmpty())
.mapToInt(cats -> {
cats.forEach(Cat::giveFood);
return cats.size();
})
.findAny()
.ifPresent(count -> logger.info("Processing for cats: " + count));
Ответ 2
Ваш текущий код намного лучше без потока и может быть сокращен до:
if (!cats.isEmpty()) {
logger.info("Processing for cats: " + cats.size());
}
cats.forEach(Cat::giveFood); // Assuming giveFood is a stateless operation
Ответ 3
cats.stream()
.peek(Cat::giveFood)
.findAny().ifPresent(cat -> logger.info("Processing for cats: " + cats.size()));
Ответ 4
Я согласен с @Lino. Это еще одна альтернатива, основанная на его идее:
List<Cat> cats = petStore.getCatsForSale();
cats.stream().limit(1)
.flatMap(c -> {
logger.info("Processing for cats: " + cats.size());
return cats.stream();
}).forEach(Cat::giveFood);
Ответ 5
Вы можете использовать этот трюк, это не лучшее решение, и вы возвращаете неиспользованное значение, но оно работает:
petStore.getCatsForSale().stream().peek(Cat::giveFood)
.findAny() // the trick
.orElseGet(() -> {
System.out.println("Cats" + count); // your log
return null; // will be ignored
});