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:
Like this:
Like Loading...
Published by lukaseder
I made jOOQ
View all posts by lukaseder
Java 8 provides also method list.replaceAll(unaryOperator) . (I know it does not match cases in blogpost since it is not aware of index, I just landed to this page googling for this method. Of course, having list.replaceAllIndexAware(BiFunction<Integer,T,T>) method in JDK would be handy solution.)
Cool, thanks for the pointer.