Допустим, у нас есть следующий базовый список:
[["foo"],["bar"]]
и входная строка "a"
Я хочу добавить входную строку к каждому списку в списке, в результате чего:
[["a", "foo"], ["a", "bar"]]
Эквивалент Javascript будет:
const base = [["foo"], ["bar"]]
const prefix = "a"
const prefixedBase = base.map(it => [prefix, ...it])
Как этого можно достичь, используя аналогичный идиоматический формат с потоками Java?
Я бы не стал использовать здесь потоковую операцию. Как сказал @user85421. Если еще не на Java 21, с l.add(0, "a")
.
Согласитесь, addFirst или add(0, «a») — хорошие альтернативы, если разумно, что входные данные могут быть изменены. Спасибо за ваши Коментарии.
Подумайте о том, можно ли и нужно ли изменить исходный список. Не ждите, что пользователи, отвечающие на вопрос о Java, прочтут ваш код JavaScript или сделают предположения на его основе.
Это не было обязательным требованием. Поэтому я оценил ваш комментарий и добавил его как вариант. Извините, если это было неясно.
Идиоматическое решение с использованием потоков Java, которое я нашел для этого, выглядит следующим образом:
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();
Хотя он и не такой лаконичный, как Javascript, он выполняет свою работу без большого количества кода. Однако важно отметить, что использование потоков Java требует важного компромисса между краткостью и читабельностью.
Для полноты эквивалентный код без потоков Java будет таким:
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);
}
Обновлено: Основываясь на других ответах и комментариях, если базовый список изменяем, addFirst
или add(0, prefix)
также можно использовать как очень краткое решение:
for (var subList: base) {
subList.addFirst(prefix); // add(0, prefix) before Java 21
}
В Java 21+:
strings.addFirst( "a" )
В более ранней версии Java:
strings.add( 0, "a" )
List#addFirst
Если вложенные списки можно изменять, в Java 21+ мы можем просто добавить первый элемент.
Сначала несколько примеров данных.
List < List < String > > listOfListsOfStrings =
List.of(
new ArrayList <>( List.of( "Foo" ) ) ,
new ArrayList <>( List.of( "Bar" ) )
);
System.out.println( "listOfListsOfStrings = " + listOfListsOfStrings );
listOfListsOfStrings.toString() = [[Foo], [Bar]]
Затем мы добавляем в начало каждого вложенного списка.
listOfListsOfStrings.forEach( strings -> strings.addFirst( "a" ) );
listOfListsOfStrings.toString() = [[a, Foo], [a, Bar]]
Кстати, если вы часто вставляете элементы в List
, рассмотрите возможность использования LinkedList , а не ArrayList . См. Когда использовать LinkedList вместо ArrayList в Java?.
Метод addFirst
является частью функции Sequenced Collections.
См. JEP 431. А еще смотрите хорошую презентацию Стюарта Маркса.
Действительно, вы можете захотеть объявить список списков более общего типа — упорядоченной коллекцией упорядоченных коллекций.
SequencedCollection < SequencedCollection < String > > seqcolOfSeqcolOfStrings =
List.of(
new ArrayList <>( List.of( "Foo" ) ) ,
new ArrayList <>( List.of( "Bar" ) )
);
…
Мой предпочтительный ответ. Если еще нет в Java 21, можно использовать strings.add( 0, "a" )
.
Используя потоки Java, вы можете добиться этого, как показано ниже.
List<List<String>> parentLList = Arrays.asList(
Arrays.asList("foo"),
Arrays.asList("bar")
);
// Input string to prepend
String prependString = "a";
// preprend the input to each list using stream
List<List<String>> yourResult = parentLList.stream()
.map(innerList -> {
List<String> newList = new ArrayList<>();
newList.add(prependString);
newList.addAll(innerList);
return newList;
})
.collect(Collectors.toList());
Ваш результат — это желаемый список здесь.
если мы получили
List<List<String>> base
, тоbase.forEach(l -> l.addFirst("a"));
должно подойти (исходные подсписки изменены,addFirst()
доступен начиная с Java 21)