Search code examples
javalambdajava-8observablelistcollectors

Collectors lambda return observable list


Is it possible for Collectors to return me a ObservableArrayList? A little like this:

ObservableList<String> newList = list.stream().
        filter(x -> x.startsWith("a").
        collect(Collectors.toCollection(ObservableArrayList::new));

Solution

  • ObservableLists are created with the static factories from the FXCollections class.

    As noted by Louis Wasserman in the comments, this can be done using toCollection:

    ObservableList<String> newList = 
            list.stream()
                .filter(x -> x.startsWith("a"))
                .collect(Collectors.toCollection(FXCollections::observableArrayList));
    

    You could also do the following, which first collects the stream into a List and then wraps it inside an ObservableList.

    ObservableList<String> newList = 
            list.stream()
                .filter(x -> x.startsWith("a"))
                .collect(Collectors.collectingAndThen(toList(), l -> FXCollections.observableArrayList(l)));
    

    (which unfortunately enough does not compile on Eclipse Mars 4.5.1 but compiles fine on javac 1.8.0_60).

    Another possibility is to create a custom Collector for this. This has the advantage that there is no need to first use a List. The elements are directly collected inside a ObservableList.

    ObservableList<String> newList = 
            list.stream()
                .filter(x -> x.startsWith("a"))
                .collect(Collector.of(
                    FXCollections::observableArrayList,
                    ObservableList::add,
                    (l1, l2) -> { l1.addAll(l2); return l1; })
                );