Вопрос

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

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

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

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

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

Это было полезно?

Решение

На самом деле, вероятно, " best " способ инициализации 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");
}};

Тем не менее, я не слишком люблю этот метод, потому что в конечном итоге вы получаете подкласс <=>, который имеет инициализатор экземпляра, и этот класс создается только для создания одного объекта - который выглядит как немного излишне для меня.

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

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

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

Другие советы

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

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

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

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

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

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

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

Простой ответ

В 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.set поддержку массива, поэтому он не может изменить длину.
Но вы можете позвонить Arrays.asList, так что он все еще изменчив.

<Ч>

Вы можете сделать Alt+Enter еще короче с помощью статического импорта:

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

Статический импорт:

import static java.util.Arrays.asList;  

Что любая современная IDE предложит и автоматически сделает для вас.
Например, в IntelliJ IDEA вы нажимаете Static import method... и выбираете List.of.

<Ч>

Однако я не рекомендую сокращать метод Java 9 of, потому что просто Stream вводит в заблуждение.
java.util.ArrayList уже достаточно короткий и хорошо читается.

<Ч>

Использование ArrayList s

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

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

Вы можете объединить LinkedList s:

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

Или вы можете перейти от Arrays.asList() к void method(...):

import static java.util.stream.Collectors.toList;

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

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

<Ч>

Если вы действительно особенно нуждаетесь в BufferedInputStream

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

  

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

<Ч>

Если вы хотите одновременно предварительно заполнить <=> и добавить к нему (почему?), используйте

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");

или используя <=>:

import static java.util.stream.Collectors.toCollection;

ArrayList<String> strings = Stream.of("foo", "bar")
                             .collect(toCollection(ArrayList::new));
strings.add("baz");

Но опять же, лучше просто использовать <=> напрямую, а не собирать его в <=>.

<Ч>

Программа для интерфейсов, а не для реализаций

Вы сказали, что объявили список как <=> в своем коде, но делать это следует только в том случае, если вы используете какой-либо элемент <=>, которого нет в <=>.

Что вы, скорее всего, не делаете.

Обычно вы должны просто объявить переменные в наиболее общем интерфейсе, который вы собираетесь использовать (например, <=>, <=> или <=>), и инициализировать их с конкретной реализацией (например, <=>, < => или <=>).

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

Например, если вы передаете <=> в <=>:

// 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
}
<Ч>

Другим примером всегда будет объявление переменной <=>, хотя обычно это <=> или <=>, потому что скоро вы или кто-то другой захотите использовать какой-то другой тип <=>.

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

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

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

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

С помощью гуавы вы можете написать:

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

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

Литералы коллекции не попали в Java 8, но можно использовать 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));
import com.google.common.collect.ImmutableList;

....

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

С 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 г.

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

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

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

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;
}

В 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 имеет много преимуществ по сравнению с предыдущими:

  1. Эффективность использования пространства
  2. Неизменность
  3. Резьбонадежный

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

С помощью коллекций Eclipse вы можете написать следующее:

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.

О самом компактном способе сделать это:

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

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

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

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

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

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

Фрагмент кода:

String [] arr = {"Sharlock", "Homes", "Watson"};

List<String> names = Arrays.asList(arr);

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

class A{}
class B extends A{}

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

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

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

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

Нравится Том сказал:

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 набор, который потребует повторной компиляции, если список потребуется изменить в будущем.

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;
    }
}

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

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

В этом случае, я думаю, вам не понадобился бы ваш ArrayList.

P.S. Рэндьяа продемонстрировала еще один приятный способ с использованием метода статической утилиты Коллекции.Добавить все.

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.

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

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

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

Попробуйте использовать следующую строку кода:

Collections.singletonList(provider)

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

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

В 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.

Collections.singletonList(messageBody)

Если вам нужен список из одного элемента !

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

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

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);
    }
}

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

Вот код с помощью 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.

Для меня Arrays.asList () - лучший и удобный. Мне всегда нравится инициализировать этот путь. Если вы новичок в коллекциях Java, я бы хотел, чтобы вы ссылались на инициализацию ArrayList

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

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");

Я создаю список messageTemplate из XML-файла, сохраненного по пути ранее в статическом контексте

public final class TemplateStore {

    private TemplateStore(){}

    private static final String [] VERSIONS = {"081"};
    private static final String TEMPLATE_FILE_MASK = "template/EdiTemplates_v%s.xml";
    private static final String ERROR = "Error In Building Edifact Message Template Store";

    public static final List<MessageTemplate> TEMPLATE_LIST = Arrays.stream(VERSIONS)
            .map(version -> TemplateStore.class
                    .getClassLoader().getResourceAsStream(String.format(TEMPLATE_FILE_MASK, version)))
            .map(inputStream -> {
                try {
                    return ((EdiTemplates) JAXBContext.newInstance(EdiTemplates.class).createUnmarshaller()
                            .unmarshal(inputStream)).getMessageTemplate();
                } catch (JAXBException e) {
                    throw new IllegalArgumentException(ERROR, e);
                }})
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
}

На самом деле, это можно сделать в одну строку:

Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top