Есть ли хороший способ отфильтровать список с помощью потоков и получить список элементов или NULL, если ни один элемент не прошел фильтр? - PullRequest
0 голосов
/ 18 января 2020

В настоящее время я делаю:

List<MyObj> nullableList = myObjs.stream().filter(m -> m.isFit()).collect(Collectors.toList());
if (nullableList.isEmpty()) {
    nullableList = null;
}

Есть ли лучший способ? Что-то вроде Collectors.toListOrNullIfEmpty ()?

Ответы [ 2 ]

3 голосов
/ 18 января 2020

Не существует такой вещи, вы могли бы сделать вспомогательный метод, который в основном будет:

.collect(
        Collectors.collectingAndThen(
            Collectors.toList(),
            x -> x.isEmpty() ? null : x)
);

Но вы тут напрашиваетесь на неприятности. Просто верните этот пустой список вместо null, если только вы не хотите, чтобы абоненты в конечном итоге вас ненавидели.

Если вы действительно хотите такой коллекционер:

static class PlzDont<T> implements Collector<T, List<T>, List<T>> {


    @Override
    public Supplier<List<T>> supplier() {
        return ArrayList::new;
    }

    @Override
    public BiConsumer<List<T>, T> accumulator() {
        return List::add;
    }

    @Override
    public BinaryOperator<List<T>> combiner() {
        return (left, right) -> {
            left.addAll(right);
            return left;
        };
    }

    @Override
    public Function<List<T>, List<T>> finisher() {
        return x -> x.isEmpty() ? null : x;
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Set.of();
    }
}
1 голос
/ 18 января 2020

Я на самом деле не уверен, что вы должны так поступить. Иногда люди пишут ужасный код, пытаясь сделать его проще. Я бы оставил этот случай с дополнительным if после потока, как в вашем коде. Но вы можете найти код, который вы ищете ниже c:

public class Demo {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        List<Integer> nullableList = list.stream()
                .filter(m -> m > 2)
                .collect(Collectors.collectingAndThen(
                        Collectors.toList(), filtered -> filtered.isEmpty() ? null : filtered
                ));
        System.out.println(nullableList);
    }
}
...