How to Use Java 8 Streams to Swiftly Replace Elements in a List
Imagine you have a list of items:
List<String> books = Arrays.asList( "The Holy Cow: The Bovine Testament", "True Hip Hop", "Truth and Existence", "The Big Book of Green Design" );
(Don’t judge me. Books from this random book generator)
Now you’d like to create a new list where the third item only is replaced by some new value:
List<String> books = Arrays.asList( "The Holy Cow: The Bovine Testament", "True Hip Hop", "Pregnancy For Dummies", // New book at index 2 "The Big Book of Green Design" );
Of course, you could go and either modify the original list:
books.set(2, "Pregnancy For Dummies");
… or create a copy of the original list and then modify that copy:
List<String> copy = new ArrayList<>(books); copy.set(2, "Pregnancy For Dummies");
But if you want to write a one-liner to do the same in a functional style, you’ll write the following, using jOOλ
seq(books) .zipWithIndex() .map(t -> t.v2 == 2 ? "Pregnancy For Dummies" : t.v1) .toList();
With the JDK standard Streams API, things get a bit harder. You could write:
Stream.concat( Stream.concat( books.stream().limit(2), Stream.of("Pregnancy For Dummies") ), books.stream.skip(3) ).collect(Collectors.toList());
That would be a bit unfortunate, though, as the first part of the stream would need to be traversed twice – once for the limit and once for the skipping (see also our post about the caveats of OFFSET pagination in SQL)
Swift or not?
Clearly, the JDK APIs won’t help you to write concise functional logic, as can be seen above and the “imperative” style is more straight-forward. We’ve written about this before. This has also been our main motivation to create jOOλ.
If you’re looking for even more functional bliss, do also have a look at the following libraries:
Reference: | How to Use Java 8 Streams to Swiftly Replace Elements in a List from our JCG partner Lukas Eder at the JAVA, SQL, AND JOOQ blog. |
Sure, if you’re replacing via index. But if you’re doing that, you should probably use a collection type that already does a copy on a change. If you’re looking to replace the book called “Truth and Existence” with “Pregnancy for Dummies”, which is probably more likely, all you need is:
books.stream().map(t -> “Truth and Existence”.equals(t) ? “Pregnancy for Dummies” : t).collect(Collectors.toList());