Java8: Stream filter, map and joining with an alternative result if the stream is empty Given a list of integers, I would like to:


filter odds numbers
produce a list inside brackets: [n1, n2, n3]
if the list is empty it should be a dash -




My current implementation is:

private static String doIt(List&lt;Integer&gt; list) {
    List&lt;String&gt; l = list.stream()
            .filter(i -&gt; (i % 2 == 0))
            .map(Object::toString)
            .collect(Collectors.toList());

    if (l.isEmpty()) {
        return "-";
    }
    return l.stream()
            .collect(Collectors.joining("; ", "[", "]"));
}


I am wondering if it is possible to do it without the intermediate list result l.

There is a problem with following implementation:

private static String doIt(List&lt;Integer&gt; list) {
    return list.stream()
            .filter(i -&gt; (i % 2 == 0))
            .map(Object::toString)
            .collect(Collectors.joining("; ", "[", "]"));
}


The result in case of empty list is [] (expected is -)



Test method:

public static void main(String[] args) {
    System.out.println(doIt(Arrays.asList(1, 2, 3)));
    System.out.println(doIt(Arrays.asList(2, 3, 4)));
    System.out.println(doIt(Arrays.asList(1, 3)));
}


Expected Result:

[2]
[2; 4]
-
You can use reduce, it returns an Optional that is empty if the stream is empty. You can use map to create the csv (or reduce) and add the brackets and orElse to return "-".

private static String doIt(List&lt;Integer&gt; list) {
    return list.stream()
            .filter(i -&gt; (i % 2 == 0))
            .map(Object::toString)
            .reduce((left, right)-&gt; left+"; "+right)
            .map(csv -&gt; "["+csv+"]")
            .orElse("-");
}