Let's say we have the following base list:
[["foo"],["bar"]]
and the input string "a"
I want to prepend the input string to each list in the list, which results in:
[["a", "foo"], ["a", "bar"]]
The Javascript equivalent would be:
const base = [["foo"], ["bar"]]
const prefix = "a"
const prefixedBase = base.map(it => [prefix, ...it])
How can this be achieved using a similar idiomatic format with Java streams?
The idiomatic solution using Java streams I found for this is as follows:
var base = List.of(List.of("foo"), List.of("bar"));
var prefix = "a";
var prefixedBase = base.stream()
.map(it -> Stream.concat(Stream.of(prefix), it.stream()).toList())
.toList();
While not as concise as Javascript, it does the job without much code. However, it's important to note that using Java streams requires an important trade-off between conciseness and readability.
For the sake of completeness, the equivalent code without Java streams would be:
var base = List.of(List.of("foo"), List.of("bar"));
var prefix = "a";
var prefixedBase = new ArrayList<List<String>>();
for (var subList: base) {
var newSubList = new ArrayList<String>();
newSubList.add(prefix);
newSubList.addAll(subList);
prefixedBase.add(newSubList);
}
EDIT: Based on other answers and comments, if the base list is mutable, addFirst
or add(0, prefix)
can also be used as a very concise solution:
for (var subList: base) {
subList.addFirst(prefix); // add(0, prefix) before Java 21
}