Java 8 collect() only isPresent() Необязательные значения

Есть ли более элегантный способ практически реализовать это в Java 8?

list.stream()
    .map(e -> myclass.returnsOptional(e))
    .filter(Optional::isPresent)
    .map(Optional::get)
    .collect(Collectors.toList());

Я говорю о filter(Optional::isPresent), а затем map(Optional::get), я хочу изящно собирать только в списке Optional результаты, которые имеют значение.

Ответ 1

В вашем случае вы можете использовать один flatMap вместо комбинаций map filter и снова map. Для этого лучше определить отдельную функцию для создания потока: public private static Stream<Integer> createStream(String e), чтобы не было нескольких строк кода в выражении лямбда.

Пожалуйста, см. мой полный демонстрационный пример:

 public class Demo{
    public static void main(String[] args) {
        List<String> list = Arrays.asList("1", "2", "Hi Stack!", "not", "5");
        List<Integer> newList = list.stream()
                .flatMap(Demo::createStream)
                .collect(Collectors.toList());
        System.out.println(newList);
    }

    public static Stream<Integer> createStream(String e) {
        Optional<Integer> opt = MyClass.returnsOptional(e);
        return opt.isPresent() ? Stream.of(opt.get()) : Stream.empty();
    }
}


class MyClass {
    public static Optional<Integer> returnsOptional(String e) {
        try {
            return Optional.of(Integer.valueOf(e));
        } catch (NumberFormatException ex) {
            return Optional.empty();
        }
    }
}

в случае, если returnOptional не может быть статическим, вам нужно будет использовать выражение "стрелка" вместо "ссылки на метод"

Ответ 2

Не уверен, что это так отличается, но вы можете просто фильтровать на основе вашего опционального, вместо того, чтобы приобретать опцию и фильтровать дальше. Что-то вроде этого?

list.stream()
    .filter(e -> myclass.returnsOptional(e).isPresent())
    .collect(Collectors.toList());

Примечание. Это будет работать, только если returnOptional возвращает тот же тип объекта, что и исходные типы элементов списка.