user3663882 user3663882 - 4 months ago 27
Java Question

Collector returning singletonList if toList returned empty list

I have quite a large stream pipeline and therefore would like to keep it clean. I have the following part of larger pipeline

Integer defaultInt;
//...
Stream<Integer> ints;
ints.filter(/* predicate_goes_here */).collect(toSingletonIfEmptyCollector);


Where
toSingletonIfEmptyCollector
is supposed to act the same as
Collectors.toList()
does if it returns non-emtpy list and
Collections.singletonList(defaultInt)
if
Collectors.toList()
returned empty.

Is there a shorter way to implement it (e.g. by composing standard collectors provided in JDK) rather then implementing all
Collector
's method from scratch?

Answer

You can use collectingAndThen and perform an additional finisher operation on the built-in toList() collector that will return a singleton list in case there was no elements.

static <T> Collector<T, ?, List<T>> toList(T defaultValue) {
    return Collectors.collectingAndThen(
              Collectors.toList(), 
              l -> l.isEmpty() ? Collections.singletonList(defaultValue) : l
           );
}

It would be used like this:

System.out.println(Stream.of(1, 2, 3).collect(toList(5))); // prints "[1, 2, 3]"
System.out.println(Stream.empty().collect(toList(5))); // prints "[5]"
Comments