javalistjava-8java-stream

How to build a new list containing all entries from existing list AND a copy of each entry with one field modified?


I have a list of some Object called list. Using list.stream(), I need to create a new list of the same Object where the new list contains all of the original entries AND the new list contains a copy of each entry with one field modified. I know how to do this using list.stream() twice but I'd like to do it under one stream.

This is how I've accomplished the task using list.stream() twice

newList = list.stream().collect(Collectors.toList());
newList.addAll(list.stream().map(l -> {SomeObject a = new SomeObject(l);
                      a.setField1("New Value");
                      return a;
                      }).collect(Collectors.toList())
                );

Solution

  • Use flatMap (assuming you don't mind the original and derived values being interleaved):

    newList = list.stream()
        .flatMap(l -> {
          SomeObject a = new SomeObject(l);
          a.setField1("New Value");
          return Stream.of(l, a);
        })
        .collect(toList());
    

    If it's just that you don't want to use stream() twice, you could avoid the first one using addAll; and the unnecessary collect for the second:

    newList = new ArrayList<>(list.size() * 2);
    newList.addAll(list);
    list.stream()
        .map(l -> {
            SomeObject a = new SomeObject(l);
            a.setField1("New Value");
            return a;
        })
        .forEach(newList::add);