Вопрос по java – Инициализация ArrayList в одну строку

2417

Я хочу создать список опций для тестирования. Сначала я сделал это:

<code>ArrayList<String> places = new ArrayList<String>();
places.add("Buenos Aires");
places.add("Córdoba");
places.add("La Plata");
</code>

Затем я изменил код следующим образом:

<code>ArrayList<String> places = new ArrayList<String>(
    Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
</code>

Есть лучший способ сделать это

Если это предназначено для юнит-тестирования, попробуйте отличную игру. Вы можете написать свой тестовый код в нем во время тестирования Java-кода и использоватьArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"] ripper234
В Java SE 7 вы можете заменить параметризованный тип конструктора пустым набором параметров типа (<>): Map <String, List <String >> myMap = new HashMap <> (); Rose
use инициализация двойной связи:) Mohammadreza Khatami
Stream.of ("val1", "val2"). Collect (Collectors.toList ()); // создает ArrayList, решение Java8. torina

Ваш Ответ

30   ответов
3

с помощью массивов вы можете инициализировать список массивов в одну строку,

List<String> strlist= Arrays.asList("aaa", "bbb", "ccc");
7

Самый компактный способ сделать это:

Double array[] = { 1.0, 2.0, 3.0};
List<Double> list = Arrays.asList(array);
1790

На самом деле, вероятно, «лучший» способ инициализацииArrayList - это метод, который вы написали, так как ему не нужно создавать новыйList в любом случае

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");

Подвох в том, что для того, чтобы ссылаться на это, нужно набрать немного текстlist экземпляр

Существуют альтернативы, такие как создание анонимного внутреннего класса с инициализатором экземпляра (также известный как «инициализация двойной скобкой»):

ArrayList<String> list = new ArrayList<String>() {{
    add("A");
    add("B");
    add("C");
}};

Однако я не слишком люблю этот метод, потому что в итоге получается подклассArrayList, у которого есть инициализатор экземпляра, и этот класс создан только для создания одного объекта - мне это кажется немного излишним.

Что было бы хорошо, если бы Коллекция Литерал предложение для Project Coin было принято (его планируется ввести в Java 7, но вряд ли оно будет частью Java 8).:

List<String> list = ["A", "B", "C"];

К сожалению, это тебе не поможет, так как инициализирует неизменяемыйList а неArrayList и, кроме того, он еще не доступен, если он когда-либо будет.

Видеть Stackoverflow.com / вопросы / 924285 для получения дополнительной информации об инициализации двойной скобки, плюсы и минусы. Eddie
@ Эдди: Хороший вызов для ссылки - одного предложения об инициализации в двойных скобках недостаточно для полного описания. coobird
Only работает, если вы не полагаетесь на Auto Boxing List <Double> list = [1.0, 2.0, 3.0]; терпит неудачу. Richard B
Ну что ж, просто покажу - синтаксический сахар одного человека - это синтаксический диабет другого человека. Я буду держаться подальше от этих «альтернатив». corsiKa
Так как этот ответ является самым популярным и упоминавшимся Project Coin, я думаю, вы должны упомянуть, что java 9 поставляется с синтаксисом List.of (...): Docs.oracle.com / JavaSE / 9 / документы / API / Java / Util / list.html # из-E ...- Asaf
3

Попробуйте эту строку кода:

Collections.singletonList(provider)
Добавьте краткое описание вашего ответа. Morales Batovski
1918

Было бы проще, если бы вы просто объявили его какList - это должен быть ArrayList?

List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");

Или если у вас есть только один элемент:

List<String> places = Collections.singletonList("Buenos Aires");

Это будет означать, чтоplaces являетсянеизменны (попытка изменить это приведет кUnsupportedOperationException исключение будет брошено).

Чтобы создать изменяемый список, который является конкретнымArrayList вы можете создатьArrayList из неизменного списка:

ArrayList<String> places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
@ Marcase: Разве вы не можете изменить свой класс, чтобы использовать List вместо ArrayList? Lawrence Dol
Согласно моему ответу, если вы не используете методы, специфичные дляArrayList, было бы лучше изменить объявление наList. Укажите интерфейсы, а не реализации. Christoffer Hammarström
@ Christoffer Hammarström: если он изменит декларацию наСписо и используетList <String> place = Arrays.asList (...); он не сможет использовать Places.add ( "блаб") maks
Просто быть чистым,asList(...) возвращает фиксированный размерList который взрывается при мутирующих операциях типаremove а такжеclear, вещиList контракт претензий в поддержку. Даже если вы оставили объявление какList, тебе все равно нужно использоватьList l = new ArrayList(asList(...)), чтобы получить объект, который не генерирует исключения OperationNotSupported. Лисков Принцип подстановки кого-нибудь? Splash
@ Splash:remove а такжеclear - необязательные операции вList, такasList(...) выполняет контракт. Нигде ОП не говорит, что ему нужно добавить больше элементов позже, пример простоList это нужно инициализировать тремя элементами. Christoffer Hammarström
715
Простой ответ

В Java 10 или более поздней версии:

var strings = List.of("foo", "bar", "baz");

В Java 9 или более поздней версии:

List<String> strings = List.of("foo", "bar", "baz");

Это даст тебе неизменноеList, поэтому его нельзя изменить.
Что вам нужно в большинстве случаев, когда вы его предварительно заполняете.

Ява 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 9List.of метод, потому что простоof сбивает с толку.
List.of уже достаточно короткий и хорошо читает.

С помощьюStreams

Почему это должно бытьList?
С Java 8 или более поздней версии вы можете использоватьStream который более гибкий:

Stream<String> strings = Stream.of("foo", "bar", "baz");

Ты можешь объединитьStreams:

Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
                                       Stream.of("baz", "qux"));

Или ты можешь пойти сStream вList:

List<String> strings = Stream.of("foo", "bar", "baz").collect(toList());

Но желательно, просто используйтеStream не собирая его вList.

Если тыдействительн конкретно нуженjava.util.ArrayList

(Вероятно, нет.)
ЦитироватьJEP 269 (выделение мое):

Eсть маленький набор вариантов использования для инициализации изменяемого экземпляра коллекции с предопределенным набором значений. Обычно желательно, чтобы эти предопределенные значения были в неизменяемой коллекции, а затем инициализировать изменяемую коллекцию с помощью конструктора копирования.

Если хочешьи то и друго заранее заполнить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:

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.

@Веселый Роджер:Arrays.asList - это статический метод. Видеть Docs.oracle.com / JavaSE / 1.5.0 / документы / руководство / язык / ... Christoffer Hammarström
@ ChristofferHammarström В этом случае мой ум новичка говорит мне, что статический импорт имеет сильное сходство с глобальными переменными и опасностями, которые имеют отношение к такому использованию. Правильно ли это предположение и является ли это причиной того, что подобный ответ выше получил больше голосов? jollyroger
Ответ, о котором вы говорите, был сделан годом ранее. И нет, проблема с глобальными переменными в том, что они изменчивы. Они не имеют ничего общего со статическим импортом. Christoffer Hammarström
Если вам не нужен статический импорт, вы также можете определить полный путь к статическому методу asList, например: List <String> strings = java.util.Arrays.asList ("", ""); Geert Weening
Или вы можете использовать import java.util.Arrays; и Arrays.asList ("", ""); Вам не нужно использовать статический импорт. Вам не нужно использовать полный путь. Статические методы не заботятся об импорте. Они просто раздражаются, если вы используете экземпляр, чтобы найти их. candied_orange
105

Если тебе нужен простой список размером 1:

List<String> strings = new ArrayList<String>(Collections.singletonList("A"));

Если вам нужен список из нескольких объектов:

List<String> strings = new ArrayList<String>();
Collections.addAll(strings,"A","B","C","D");
54

С Гуавы ты можешь написать

ArrayList<String> places = Lists.newArrayList("Buenos Aires", "Córdoba", "La Plata");

В Гуаве есть и другие полезные статические конструкторы. Вы можете прочитать о нихВо.

Я уверен, что ты сможешь сделать это просто с помощьюjava.util.Arrays такие как,List<String> names = Arrays.asList("Beckah", "Sam", "Michael"); beckah
@ beckah метод Arrays.asLists создает объект типа List, тогда как вопрос о создании ArrayList Paweł Adamski
31

но можно использовать Stream API для инициализации списка в одну довольно длинную строку:

List<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toList());

Если вам нужно убедиться, что вашList являетсяArrayList:

ArrayList<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toCollection(ArrayList::new));
26
import com.google.common.collect.ImmutableList;

....

List<String> places = ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");
Я не хочу добавлять новую зависимость просто для этого. Macarse
Это так же, какCollections.unmodifiableList(Arrays.asList("Buenos Aires", "Córdoba", "La Plata")), который становитсяunmodifiableList(asList("Buenos Aires", "Córdoba", "La Plata")) со статическим импортом. Для этого вам не нужны Google Collections. Christoffer Hammarström
Нет, это не то же самое. Поскольку ImmutableList документирует свою неизменность в типе результата, когда unmodifiableList маскирует его как обычный List. David Pierre
Вместо неизменного коллекции Google также предлагают список изменяемых массивов: List <String> = Lists.newArrayList ("Буэнос-Айрес", "Кордова", "Ла-Плата"); L. Holanda
Ты собираешься пройти этоImmutableList другим методам, которые принимаютList и потом ты все равно потерял эту документацию. Christoffer Hammarström
23

СJava 9, как предложено вJDK Предложение по улучшению - 269, это может быть достигнуто с помощью Коллекция литералов сейчас как -

List<String> list = List.of("A", "B", "C");

Set<String> set = Set.of("A", "B", "C");

Также аналогичный подход будет применяться кMap также

Map<String, String> map = Map.of("k1", "v1", "k2", "v2", "k3", "v3")

который похож на Коллекция Литерал предложение как сказано @coobird. Также уточняется в документе JEP -

Альтернативы

Изменения языка были рассмотрены несколько раз и отклонены:

Предложение монет проекта, 29 марта 2009 года

Проект монетного предложения, 30 марта 2009 г.

JEP 186 обсуждение lambda-dev, январь-март 2014 года

Языковые предложения были отложены в предпочтении перед библиотечным предложением, как описано в этомсообщение

Related => В чем смысл перегруженных методов фабрики удобства для коллекций в Java 9

22

Вы можете создать фабричный метод:

public static ArrayList<String> createArrayList(String ... elements) {
  ArrayList<String> list = new ArrayList<String>();
  for (String element : elements) {
    list.add(element);
  }
  return list;
}

....

ArrayList<String> places = createArrayList(
  "São Paulo", "Rio de Janeiro", "Brasília");

Но это не намного лучше, чем твой первый рефакторинг.

Для большей гибкости он может быть общим:

public static <T> ArrayList<T> createArrayList(T ... elements) {
  ArrayList<T> list = new ArrayList<T>();
  for (T element : elements) {
    list.add(element);
  }
  return list;
}
Взгляните на исходный пост, он запрашивает инициализацию массива водна лини, а не 7 дополнительных строк. L. Holanda
@ LeoHolanda: Создание фабричных методов для каждой мелочи - это слишком много, я согласен. Но В зависимости о ситуации и о том, сколько раз этот метод будет использоваться, возможно, имеет смысл его создать. Создание дополнительных слоев абстракции предназначено дляудалят сложность, создавая больше Смысл методы, которые захватывают Намерение дизайнера. Jordão
15

В Java 9 мы можем легко инициализироватьArrayList в одну строку:

List<String> places = List.of("Buenos Aires", "Córdoba", "La Plata");

ил

List<String> places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata"));

Этот новый подход Java 9 имеет много преимуществ перед предыдущими:

Пространственная эффективность Неизменность Безопасный

См. Этот пост для более подробной информации -> В чем разница между List.of и Arrays.asList?

7

С Затмение Коллекции (ранееGS Коллекции), вы можете написать следующее:

List<String> list = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata");

Вы также можете более точно указать типы и то, являются ли они изменяемыми или неизменяемыми.

MutableList<String> mList = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableList<String> iList = Lists.immutable.with("Buenos Aires", "Córdoba", "La Plata");

Вы также можете сделать то же самое с наборами и сумками:

Set<String> set = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata");
MutableSet<String> mSet = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableSet<String> iSet = Sets.immutable.with("Buenos Aires", "Córdoba", "La Plata");

Bag<String> bag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata");
MutableBag<String> mBag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableBag<String> iBag = Bags.immutable.with("Buenos Aires", "Córdoba", "La Plata");

Заметка Я коммитер в Eclipse Collections.

7

Вот другой способ:

List<String> values = Stream.of("One", "Two").collect(Collectors.toList());
7

Просто используйте приведенный ниже код следующим образом.

List<String> list = new ArrayList<String>() {{
            add("A");
            add("B");
            add("C");
}};
@ bsd Вы можете использовать этот метод для объявления списка перед вводом любого метода. Таким образом, при определении переменных класса содержимое может быть добавлено в список без необходимости вызова метода для этого. melwil
о возможности следует избегать инициализации двойных скобок. видеть : Stackoverflow.com / а / 924326/760393 Raúl
6

Вы можете использовать следующие утверждения:

Код сниппет:
String [] arr = {"Sharlock", "Homes", "Watson"};

List<String> names = Arrays.asList(arr);
Вы можете встроить первое выражение, чтобы иметь компактное решение:letters = Arrays.asList(new String[]{"A", "B", "C"}); Pavel Repin
6

(Должен быть комментарий, но слишком длинный, поэтому новый ответ). Как уже упоминалось,Arrays.asListетод @ имеет фиксированный размер, но это не единственная проблема с ним. Это также не очень хорошо обрабатывает наследование. Например, предположим, у вас есть следующее:

class A{}
class B extends A{}

public List<A> getAList(){
    return Arrays.asList(new B());
}

Вышеприведенное приводит к ошибке компилятора, потому чтоList<B> (что возвращает Arrays.asList) не является подклассомList<A>, даже если вы можете добавить объекты типа B кList<A> объект. Чтобы обойти это, вам нужно сделать что-то вроде:

new ArrayList<A>(Arrays.<A>asList(b1, b2, b3))

Это, наверное, лучший способ сделать это, особенно. если вам нужен неограниченный список или вам нужно использовать наследование.

5

Подобно Том сказал:

List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");

Но так как вы жаловались на то, что хотите ArrayList, вы должны сначала знать, что ArrayList является подклассом List, и вы можете просто добавить эту строку:

ArrayList<String> myPlaces = new ArrayList(places);

Хотя это может заставить тебя жаловаться на «производительность».

В этом случае для меня не имеет смысла, почему, поскольку ваш список предопределен, он не был определен как массив (так как размер известен во время инициализации). И если это вариант для вас:

String[] places = {"Buenos Aires", "Córdoba", "La Plata"};

В случае, если вас не волнуют незначительные различия в производительности, вы также можете очень просто скопировать массив в ArrayList:

ArrayList<String> myPlaces = new ArrayList(Arrays.asList(places));

Хорошо, но в будущем вам понадобится не только название места, но и код страны. Предполагая, что это все еще предопределенный список, который никогда не изменится во время выполнения, тогда уместно использоватьenum set, который потребует повторной компиляции, если список потребуется изменить в будущем.

enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA}

станет

enum Places {
    BUENOS_AIRES("Buenos Aires",123),
    CORDOBA("Córdoba",456),
    LA_PLATA("La Plata",789);

    String name;
    int code;
    Places(String name, int code) {
      this.name=name;
      this.code=code;
    }
}

У Enum есть статикаvalues метод, который возвращает массив, содержащий все значения перечисления в порядке их объявления, например :

for (Places p:Places.values()) {
    System.out.printf("The place %s has code %d%n",
                  p.name, p.code);
}

В таком случае, я думаю, тебе не нужен твой ArrayList.

P.S.Randyaa продемонстрировала еще один замечательный способ использования статического служебного метода Collections.addAll.

5

Java 9 имеет следующий метод для созданиянеизменны список:

List<String> places = List.of("Buenos Aires", "Córdoba", "La Plata");

который легко адаптируется для создания изменяемого списка, если требуется:

List<String> places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata"));

Аналогичные методы доступны дляSet а такжеMap.

4
List<String> names = Arrays.asList("2","@2234","21","11");
4

Вы можете использоватьStickyList от Cactoos:

List<String> names = new StickyList<>(
  "Scott Fitzgerald", "Fyodor Dostoyevsky"
);
2

На Java ты не можешь сделать

ArrayList<String> places = new ArrayList<String>( Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));

Как было указано, вам нужно выполнить инициализацию в виде двойной скобки:

List<String> places = new ArrayList<String>() {{ add("x"); add("y"); }};

Но это может заставить вас добавить аннотацию@SuppressWarnings("serial") или создать серийный UUID, который раздражает. Кроме того, большинство форматеров кода развернут это в несколько операторов / строк.

Или ты можешь сделать

List<String> places = Arrays.asList(new String[] {"x", "y" });

но тогда вы можете сделать@SuppressWarnings("unchecked").

Кроме того, в соответствии с Javadoc вы должны быть в состоянии сделать это:

List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");

Но я не могу его скомпилировать с JDK 1.6.

Неправильно! Выможе сделать первую строку, и это правильный ответ, кстати Bohemian♦
1
Collections.singletonList(messageBody)

один предме!

Коллекции из Java.util пакет.

1

Лучший способ сделать это:

package main_package;

import java.util.ArrayList;


public class Stackkkk {
    public static void main(String[] args) {
        ArrayList<Object> list = new ArrayList<Object>();
        add(list, "1", "2", "3", "4", "5", "6");
        System.out.println("I added " + list.size() + " element in one line");
    }

    public static void add(ArrayList<Object> list,Object...objects){
        for(Object object:objects)
            list.add(object);
    }
}

Просто создайте функцию, которая может иметь столько элементов, сколько вы хотите, и вызовите ее, чтобы добавить их в одну строку.

Если вы справитесь со всеми трудностями, вы можете сделать это методом шаблона вместо использования обычногоObject. Robert
1

Вот код AbacusUtil

// ArrayList
List<String> list = N.asList("Buenos Aires", "Córdoba", "La Plata");
// HashSet
Set<String> set = N.asSet("Buenos Aires", "Córdoba", "La Plata");
// HashMap
Map<String, Integer> map = N.asMap("Buenos Aires", 1, "Córdoba", 2, "La Plata", 3);

// Or for Immutable List/Set/Map
ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");
ImmutableSet.of("Buenos Aires", "Córdoba", "La Plata");
ImmutableSet.of("Buenos Aires", 1, "Córdoba", 2, "La Plata", 3);

// The most efficient way, which is similar with Arrays.asList(...) in JDK. 
// but returns a flexible-size list backed by the specified array.
List<String> set = Array.asList("Buenos Aires", "Córdoba", "La Plata");

Декларация: я разработчик AbacusUtil.

0

иализировать этот путь. Если вы новичок в коллекциях Java, я бы хотел, чтобы вы указалиArrayList инициализация

Почему Arrays.asList () лучше, чем создание нового ArrayList в одну строку сadd() методы? IgorGanapolsky
0

которая делает это?

static <A> ArrayList<A> ll(A... a) {
  ArrayList l = new ArrayList(a.length);
  for (A x : a) l.add(x);
  return l;
}

"ll "расшифровывается как" буквальный список ".

ArrayList<String> places = ll("Buenos Aires", "Córdoba", "La Plata");
-1

Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})
Могу я спросить, что это добавляет к вопросу? Этот ответ уже несколько раз охвачен другими ответами. Mysticial
Этот ответ мало что добавляет к уже существующим. Koushik Shetty
Это действительно плохое решение, так как создает РЕЗЮМЕ СПИСОК. Вы не сможете добавить что-либо еще в контейнер. Atais
-4
public static <T> List<T> asList(T... a) {
    return new ArrayList<T>(a);
}

Это реализацияArrays.asList, чтобы ты мог пойти с

ArrayList<String> arr = (ArrayList<String>) Arrays.asList("1", "2");
-1 Это не тот же класс. Paul Bellora

Похожие вопросы