Pregunta

Quiero crear una lista de opciones para fines de prueba.Al principio hice esto:

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

Luego refactoricé el código de la siguiente manera:

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

¿Hay una mejor manera de hacer esto?

¿Fue útil?

Solución

En realidad, probablemente el & "; mejor &"; La forma de inicializar el ArrayList es el método que escribió, ya que no necesita crear un nuevo List de ninguna manera:

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

El problema es que hay que escribir bastante para referirse a esa list instancia.

Hay alternativas, como crear una clase interna anónima con un inicializador de instancia (también conocido como " inicialización de doble paréntesis "):

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

Sin embargo, no me gusta demasiado ese método porque lo que termina es una subclase de <=> que tiene un inicializador de instancia, y esa clase se crea solo para crear un objeto, que parece un un poco exagerado para mí.

Lo que hubiera sido bueno sería si los Literales de colección Se aceptó la propuesta para Project Coin (estaba programada para ser introducida en Java 7, pero tampoco es probable que forme parte de Java 8):

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

Desafortunadamente no lo ayudará aquí, ya que inicializará un <=> inmutable en lugar de un <=>, y además, aún no está disponible, si alguna vez lo estará.

Otros consejos

Sería más simple si simplemente lo declararas como List ¿tiene que ser una ArrayList?

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

O si solo tiene un elemento:

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

Esto significaría que places es inmutable (intentar cambiarlo provocará una UnsupportedOperationException excepción)

Para hacer una lista mutable que sea concreta ArrayList puede crear un <=> de la lista inmutable:

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

la respuesta sencilla

En Java 10, 11, 12 o posterior:

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

En Java 9 o posterior:

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

Esto te dará un inmutable List, por lo que no se puede cambiar.
Que es lo que desea en la mayoría de los casos en los que lo completa previamente.


Java 8 o anterior:

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

Esto te dará una List respaldado por la matriz, por lo que no puede cambiar la longitud.
pero puedes llamar List.set, por lo que todavía es mutable.


Puedes hacer Arrays.asList aún más corto con una importación estática:

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

La importación estática:

import static java.util.Arrays.asList;  

Lo cual cualquier IDE moderno sugerirá y hará automáticamente por usted.
Por ejemplo, en IntelliJ IDEA presionas Alt+Enter y seleccione Static import method....


Sin embargo, no recomiendo acortar el Java 9. List.of método, porque teniendo apenas of se vuelve confuso.
List.of Ya es bastante breve y se lee bien.


Usando Streams

¿Por qué tiene que ser un List?
Con Java 8 o posterior puedes usar un Stream cuál es más flexible:

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

Puedes concatenar Streams:

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

O puedes ir desde un Stream a un List:

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

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

Pero preferiblemente, solo usa el Stream sin recogerlo a un List.


Si usted en realidad necesita específicamente un java.util.ArrayList

(Probablemente no lo hagas).
Citar JEP 269 (el énfasis es mío):

Hay un pequeño conjunto de casos de uso para inicializar una instancia de colección mutable con un conjunto predefinido de valores.Generalmente es preferible tener esos valores predefinidos en una colección inmutable y luego inicializar la colección mutable mediante un constructor de copia.


Si quieres ambos prepoblar un ArrayList y agréguelo después (¿por qué?), use

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

o en Java 8 o anterior:

ArrayList<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");

o usando Stream:

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

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

Pero nuevamente, es mejor simplemente usar el Stream directamente en lugar de recogerlo en un List.


Programa a interfaces, no a implementaciones.

Dijiste que habías declarado la lista como ArrayList en su código, pero sólo debe hacerlo si está utilizando algún miembro de ArrayList eso no esta en List.

Lo que probablemente no estés haciendo.

Por lo general, deberías declarar las variables mediante la interfaz más general que vas a utilizar (p. ej. Iterable, Collection, o List) e inicializarlos con la implementación específica (p. ej. ArrayList, LinkedList o Arrays.asList()).

De lo contrario, estará limitando su código a ese tipo específico y será más difícil cambiarlo cuando lo desee.

Por ejemplo, si estás pasando un ArrayList a un 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
}

Otro ejemplo sería siempre declarar una variable como InputStream aunque suele ser un FileInputStream o un BufferedInputStream, porque algún día, pronto, usted o alguien más querrá usar algún otro tipo de InputStream.

Si necesita una lista simple de tamaño 1:

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

Si necesita una lista de varios objetos:

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

Con Guava puede escribir:

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

En Guava también hay otros constructores estáticos útiles. Puede leer sobre ellos aquí .

Los literales de colección no llegaron a Java 8, pero es posible usar Stream API para inicializar una lista en una línea bastante larga:

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

Si necesita asegurarse de que su List es un 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");

Con Java 9, como se sugiere en Propuesta de mejora JDK - 269 , esto podría ser logrado usando literales de colección ahora como -

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

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

También se aplicaría un enfoque similar a Map también -

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

que es similar a Propuesta de Colección Literals según lo indicado por @coobird también. Más aclarado en el documento JEP también -


Alternativas

  

Los cambios de idioma se han considerado varias veces y se han rechazado:

     

Propuesta de moneda del proyecto, 29 de marzo de 2009

     

Propuesta de moneda del proyecto, 30 de marzo de 2009

     

JEP 186 discusión sobre lambda-dev, enero -Marzo 2014

     

El idioma   las propuestas se reservaron con preferencia a una propuesta basada en la biblioteca como   resumido en este mensaje.

Relacionado = > ¿Qué es? el punto de los métodos de fábrica de conveniencia sobrecargados para colecciones en Java 9

Puede crear un método de fábrica:

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

Pero no es mucho mejor que su primera refactorización.

Para una mayor flexibilidad, puede ser genérico:

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

En Java 9 podemos inicializar fácilmente un ArrayList en una sola línea:

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

o

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

Este nuevo enfoque de Java 9 tiene muchas ventajas sobre los anteriores:

  1. Eficiencia espacial
  2. Inmutabilidad
  3. Seguridad para subprocesos

Vea esta publicación para más detalles: > ¿Cuál es la diferencia entre List.of y Arrays.asList?

Con Eclipse Collections puede escribir lo siguiente:

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

También puede ser más específico sobre los tipos y si son mutables o inmutables.

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

También puede hacer lo mismo con Conjuntos y Bolsas:

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

Nota: soy un confirmador de Eclipse Collections.

La forma más compacta de hacer esto es:

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

Aquí hay otra forma:

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

Simplemente use el siguiente código de la siguiente manera.

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

Puede usar las siguientes declaraciones:

Fragmento de código:

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

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

(Debe ser un comentario, pero demasiado largo, por lo que una nueva respuesta). Como otros han mencionado, el método Arrays.asList es de tamaño fijo, pero ese no es el único problema con él. Tampoco maneja la herencia muy bien. Por ejemplo, suponga que tiene lo siguiente:

class A{}
class B extends A{}

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

Lo anterior genera un error de compilación, porque List<B> (que es lo que devuelve Arrays.asList) no es una subclase de List<A>, aunque puede agregar Objetos de tipo B a un objeto <=> . Para evitar esto, debe hacer algo como:

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

Esta es probablemente la mejor manera de hacerlo, especialmente. si necesita una lista ilimitada o necesita usar la herencia.

Me gusta Tom dijo :

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

Pero como se quejó de querer una ArrayList, primero debe saber que ArrayList es una subclase de List y simplemente puede agregar esta línea:

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

Sin embargo, eso podría hacer que te quejes de "rendimiento".

En ese caso no tiene sentido para mí, por qué, dado que su lista está predefinida, no se definió como una matriz (ya que el tamaño se conoce al momento de la inicialización). Y si esa es una opción para ti:

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

En caso de que no le importen las pequeñas diferencias de rendimiento, también puede copiar una matriz a una ArrayList de manera muy simple:

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

Bien, pero en el futuro necesita un poco más que el nombre del lugar, también necesita un código de país. Suponiendo que esta sigue siendo una lista predefinida que nunca cambiará durante el tiempo de ejecución, entonces es apropiado usar un conjunto enum, que requeriría una nueva compilación si la lista necesitara ser cambiada en el futuro.

enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA}

se convertiría en:

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

Las enumeraciones tienen un método estático values que devuelve una matriz que contiene todos los valores de la enumeración en el orden en que se declaran, por ejemplo:

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

En ese caso, supongo que no necesitarías tu ArrayList.

P.S. Randyaa demostró otra forma agradable de usar el método de utilidad estática Collections.addAll .

Java 9 tiene el siguiente método para crear un inmutable lista:

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

que se adapta fácilmente para crear una lista mutable, si es necesario:

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

Hay métodos similares disponibles para Set y Map.

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

Puede usar StickyList de Cactoos :

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

Pruebe con esta línea de código:

Collections.singletonList(provider)

Sí, con la ayuda de matrices, puede inicializar la lista de matrices en una línea,

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

En Java, no puedes hacer

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

Como se señaló, necesitaría hacer una inicialización de doble llave:

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

Pero esto puede obligarlo a agregar una anotación @SuppressWarnings("serial") o generar un UUID en serie que es molesto. Además, la mayoría de los formateadores de código lo desenvolverán en múltiples declaraciones / líneas.

Alternativamente puedes hacer

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

pero es posible que desee hacer un @SuppressWarnings("unchecked").

También según javadoc deberías poder hacer esto:

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

Pero no puedo hacer que se compile con JDK 1.6.

Collections.singletonList(messageBody)

¡Si necesita tener una lista de un elemento !

Colecciones es del paquete java.util .

La mejor manera de hacerlo:

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

Simplemente cree una función que pueda tener tantos elementos como desee y llámela para agregarlos en una línea.

Aquí está el código de 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");

Declaración & # 65306; Soy el desarrollador de AbacusUtil.

Para mí Arrays.asList () es el mejor y conveniente. Siempre me gusta inicializar de esa manera. Si es un principiante en Java Collections, me gustaría que consulte ArrayList initialization

¿Por qué no hacer una función de utilidad simple que haga esto?

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

" ll " significa " lista literal " ;.

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

Estoy creando una lista de messageTemplate a partir de un archivo xml almacenado en la ruta antes en contexto estático

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

En realidad, es posible hacerlo en una línea:

Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top