Простой ответ
В Java 10, 11, 12 или более поздней версии:
var strings = List.of("foo", "bar", "baz");
В Java 9 или более поздней версии:
List<String> strings = List.of("foo", "bar", "baz");
Это даст вам неизменный List
, поэтому его нельзя изменить.
Это то, что вы хотите в большинстве случаев, когда вы его предварительно заполняете.
Java 8 или более ранняя версия:
List<String> strings = Arrays.asList("foo", "bar", "baz");
Это даст вам List
, обеспеченный массивом, поэтому он не может изменить длину.
Но вы можете позвонить List.set
, так что он все еще изменчив.
Вы можете сделать Arrays.asList
еще короче при статическом импорте:
List<String> strings = asList("foo", "bar", "baz");
Статический импорт:
import static java.util.Arrays.asList;
Что любая современная IDE предложит и автоматически сделает для вас.
Например, в IntelliJ IDEA вы нажимаете Alt+Enter
и выбираете Static import method...
.
Однако я не рекомендую сокращать метод Java 9 List.of
, потому что просто of
может сбить с толку.
List.of
уже достаточно короткий и хорошо читается.
Использование Stream
с
Почему это должен быть List
?
В Java 8 или более поздней версии вы можете использовать Stream
, который является более гибким:
Stream<String> strings = Stream.of("foo", "bar", "baz");
Вы можете объединить Stream
s:
Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
Stream.of("baz", "qux"));
Или вы можете перейти от Stream
к List
:
import static java.util.stream.Collectors.toList;
List<String> strings = Stream.of("foo", "bar", "baz").collect(toList());
Но желательно, просто используйте Stream
, не собирая его в List
.
Если вам действительно , в частности нужен java.util.ArrayList
(Вы, вероятно, нет.)
Цитировать JEP 269 (выделено мое):
Существует небольшой набор вариантов использования для инициализации изменяемого экземпляра коллекции с предопределенным набором значений. Обычно желательно, чтобы эти предопределенные значения были в неизменяемой коллекции, а затем инициализировать изменяемую коллекцию с помощью конструктора копирования.
Если вы хотите , оба предварительно заполнить ArrayList
и добавить к нему впоследствии (почему?), Используйте
ArrayList<String> strings = new ArrayList<>(List.of("foo", "bar"));
strings.add("baz");
или в Java 8 или более ранней версии:
ArrayList<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");
или используя Stream
:
import static java.util.stream.Collectors.toCollection;
ArrayList<String> strings = Stream.of("foo", "bar")
.collect(toCollection(ArrayList::new));
strings.add("baz");
Но опять же, лучше просто использовать Stream
напрямую, а не собирать его в List
.
Программа для интерфейсов, а не для реализаций
Вы сказали, что объявили список как ArrayList
в своем коде, но вы должны делать это только в том случае, если вы используете какой-то элемент ArrayList
, которого нет в List
.
Что вы, скорее всего, не делаете.
Обычно вам следует просто объявить переменные в наиболее общем интерфейсе, который вы собираетесь использовать (например, Iterable
, Collection
или List
), и инициализировать их конкретной реализацией (например, ArrayList
, LinkedList
или Arrays.asList()
).
В противном случае вы ограничиваете свой код этим конкретным типом, и вам будет сложнее изменить его, когда захотите.
Например, если вы передаете ArrayList
void method(...)
:
// Iterable if you just need iteration, for (String s : strings):
void method(Iterable<String> strings) {
for (String s : strings) { ... }
}
// Collection if you also need .size(), .isEmpty(), or .stream():
void method(Collection<String> strings) {
if (!strings.isEmpty()) { strings.stream()... }
}
// List if you also need .get(index):
void method(List<String> strings) {
strings.get(...)
}
// Don't declare a specific list implementation
// unless you're sure you need it:
void method(ArrayList<String> strings) {
??? // You don't want to limit yourself to just ArrayList
}
Другим примером всегда будет объявление переменной InputStream
, хотя обычно это FileInputStream
или BufferedInputStream
, потому что однажды вы или кто-то еще захотите использовать какой-то другой тип InputStream
.