Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactor creation of a list with java 8 streams

I found the following code, which adds an item under certain circumstances (if its not OLD) to a list. This list get's packed in a common controls list afterwards.

    List<ListDataContent> list = new ArrayList<>();

    for (KonditionValue kondition : konditions) {
        if (kondition.getStatusKz().equals(StatusKz.OLD))
            continue;
        for (TermKondValue tilg : kondition.getTermimKonditions()) {
            if (tilg.getStatusKz().equals(StatusKz.OLD))
                continue;

            TerminKondListContent listContent = new TerminKondListContent(tilg, kondition.getChangeDatum(), funds);
            list.add(listContent);
        }
    }

    SimpleListControl listCtrl = new SimpleListControl();
    listCtrl.setDataModel(new ListDataModel(list));

I tried the following refactoring using java8 streams:

List<ListDataContent> list = konditionen.stream().map(kondition -> map(tilg, kondition.getChangeDate(), funds)).sorted().collect(Collectors.toList());
SimpleListControl listCtrl = new SimpleListControl();
listCtrl.setDataModel(new ListDataModel(list));

The problem is the map method...

private TerminKondListContent map(TermKondValue tilg, Date changeDate, BigDecimal funds) {
    if (kondition.getStatusKz().equals(StatusKz.OLD))
        return null;
    for (TermKondValue zins : kondition.getTerminkonditions()) {
        if (zins.getStatusKz().equals(StatusKz.OLD))
            return null;

        return new TerminKondListContent(tilg, changeDate, funds);
    }
    return null;
}

What can I do in the continue cases? return null? I could then filter null Values from the stream via

list.stream().filter( Objects::nonNull )

Is the use of Optionals an option here?

like image 818
Chris311 Avatar asked Oct 30 '22 07:10

Chris311


1 Answers

It is not that pretty, but you can have the following

List<ListDataContent> list = 
    konditions.stream()
              .filter(kondition -> !kondition.getStatusKz().equals(StatusKz.OLD))
              .flatMap(kondition -> 
                 kondition.getTerminTilgkonditions()
                          .stream()
                          .filter(tilg -> !tilg.getStatusKz().equals(StatusKz.OLD))
                          .map(tilg -> new AbstractMap.SimpleEntry<>(kondition, tilg))
              )
              .map(e -> new TerminKondTilgListContent(e.getValue(), e.getKey().getChangeDatum(), funds))
              .collect(Collectors.toList());

This creates a Stream<KonditionValue> and only keeps the ones where the status is not StatusKz.OLD. Then, it flat maps each of them into their TermKondTilgValues where only the TermKondTilgValue having a status not StatusKz.OLD are kept also.

Note that we keep a reference to both the TermKondTilgValue and KonditionValue because we will need afterwards, so we use a AbstractMap.SimpleEntry as holder for two values.

Finally, this Stream is mapped to the corresponding TerminKondTilgListContent and collected into a list.

like image 60
Tunaki Avatar answered Nov 09 '22 14:11

Tunaki