Фильтрация минимума необязательных значений - PullRequest
4 голосов
/ 28 января 2020

Я хочу получить минимальное значение результата функции из списка объектов. Но возвращаемое значение этой функции необязательно. Таким образом, было бы хорошо, если бы время фрагмента не было установлено, и возвращаемое значение должно было бы тогда быть Optional.empty()

public Optional<Double> getFragmentTime(int fragment) {
    ...
}

private List<Entry> entries; // will be filled in the ctor.

public Optional<Double> getMinFragmentTime(int fragment) {
    return entries.stream()
       .map(e -> e.getFragmentTime(fragment))
       .filter(Optional::isPresent)
       .map(Optional::get)
       .min(Double::compare);
}

Это правильный способ архивировать это? Два вызова функций .filter(Optional.isPresent) и .map(Optional.get) кажутся мне довольно странными, и я думаю, что для этого должно быть лучшее решение.

Ответы [ 2 ]

8 голосов
/ 28 января 2020

Вы можете использовать преимущество плоского отображения с Optional::stream, доступным с :

return entries.stream()                         // Stream<Entry>
        .map(e -> e.getFragmentTime(fragment))  // Stream<Optional<Double>>
        .flatMap(Optional::stream)              // Stream<Double>
        .min(Double::compare);                  // Optional<Double>

Обратите внимание, что .min(Double.compare); не является правильным использованием, Параметр фактически является лямбда-выражением ((d1, d2) -> Double.compare(d1, d2), которое должно быть сокращено до ссылки на метод Double::compare. Также возможно использование Comparator.comparingDouble(d -> d).

В случае вы должны придерживаться .filter(Optional::isPresent).map(Optional::get).

1 голос
/ 28 января 2020

Сначала следует использовать поток для примитивного типа, так как он имеет хорошую поддержку min().

public OptionalDouble getFragmentTime(int fragment) {
    ...
}

public OptionalDouble getMinFragmentTime(int fragment) {
    return entries.stream()
       .flatMap(e -> e.getFragmentTime(fragment).stream())
       .min();
}

OptionalDouble может доставить поток с 1 или 0 дубликатами. FlatMap для DoubleStream, а затем принимает мин.

(код не проверен.)

...