Переписать цикл с перерывом на лямбду - PullRequest
2 голосов
/ 07 ноября 2019

У меня был цикл для счетчика:

List<Mt4Report> history = ...
int counter = 0;
for (Mt4Report item : history) {
    if (item.getProfit().compareTo(BigDecimal.ZERO) < 0) {
        counter++;
    } else {
        break;
    }
}

Как я могу написать ту же идею с лямбда-выражением, что-то .findFirst().ifPresent, но с удерживающим оператором break?

Ответы [ 2 ]

4 голосов
/ 07 ноября 2019

С Java-9 и выше, вы можете использовать takeWhile подход как:

int counter = (int) history.stream()
        .takeWhile(item -> item.getProfit().compareTo(BigDecimal.ZERO) < 0)
        .count();

Для решения Java-8 вы можете посмотреть пользовательскую реализацию takeWhile, предоставленную в этот ответ . С другой стороны, менее эффективная реализация с использованием indexOf может состоять в следующем:

int count = history.stream()
        .filter(ite -> ite.getProfit().compareTo(BigDecimal.ZERO) >= 0)
        .findFirst()
        .map(history::indexOf)
        .orElse(history.size());

Поскольку Хольгер предложил улучшить вышеуказанное решение, вы можете использовать IntStream с findFirst:

int count = IntStream.range(0, history.size())
                     .filter(ix -> history.get(ix).getProfit() .compareTo(BigDecimal.ZERO) >= 0)
                     .findFirst()
                     .orElse(history.size());
1 голос
/ 07 ноября 2019

В Java 8 нет прямого решения этой проблемы, которая в основном останавливает Stream с использованием Predicate.
В Java 9 у вас есть метод takeWhile(), но в Java 8 естьнет такой вещи.
Пожалуйста, обратитесь к этот пост

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...