Domanda

Desidero creare un elenco di opzioni a scopo di test.All'inizio ho fatto questo:

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

Quindi ho rifattorizzato il codice come segue:

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

Esiste un modo migliore per farlo?

È stato utile?

Soluzione

In realtà, probabilmente il " migliore " il modo per inizializzare il ArrayList è il metodo che hai scritto, in quanto non è necessario creare un nuovo List in alcun modo:

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

Il problema è che è necessario un po 'di digitazione per fare riferimento a tale list istanza.

Esistono alternative, come creare una classe interna anonima con un inizializzatore di istanza (noto anche come " inizializzazione doppia parentesi "):

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

Tuttavia, non sono troppo affezionato a quel metodo perché quello che si ottiene è una sottoclasse di <=> che ha un inizializzatore di istanza e quella classe viene creata solo per creare un oggetto - che sembra proprio un un po 'eccessivo per me.

Quello che sarebbe stato bello se le Literals Collection proposta per Project Coin è stata accettata (era prevista per essere introdotta in Java 7, ma è improbabile che faccia parte di Java 8).

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

Sfortunatamente non ti aiuterà qui, poiché inizializzerà un <=> invece di un <=> immutabile, e inoltre non è ancora disponibile, se mai lo sarà.

Altri suggerimenti

Sarebbe più semplice se lo dichiarassi semplicemente List - deve essere un ArrayList?

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

O se hai un solo elemento:

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

Ciò significherebbe che places è immutabile (il tentativo di modificarlo provocherà la UnsupportedOperationException eccezione).

Per creare un elenco mutabile che sia un ArrayList concreto puoi creare un <=> dall'elenco immutabile:

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

La semplice risposta

In Java 10, 11, 12 o successivo:

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

In Java 9 o versioni successive:

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

Questo ti darà un immutabile List, quindi non può essere modificato.
Che è quello che vuoi nella maggior parte dei casi in cui lo stai prepopolando.


Java 8 o precedente:

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

Questo ti darà un List.set supportato dall'array, quindi non può cambiare lunghezza.
Ma puoi chiamare Arrays.asList, quindi è ancora modificabile.


Puoi rendere Alt+Enter ancora più breve con un'importazione statica:

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

L'importazione statica:

import static java.util.Arrays.asList;  

Quale qualsiasi IDE moderno suggerirà e farà automaticamente per te.
Ad esempio in IntelliJ IDEA si preme Static import method... e si seleziona List.of.


Tuttavia, non consiglio di abbreviare il metodo Java 9 of, perché avere solo Stream diventa confuso.
java.util.ArrayList è già abbastanza corto e legge bene.


Uso di ArrayList s

Perché deve essere un Iterable?
Con Java 8 o versioni successive puoi utilizzare un Collection che è più flessibile:

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

Puoi concatenare LinkedList s:

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

Oppure puoi passare da Arrays.asList() a void method(...):

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

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

Ma preferibilmente, basta usare InputStream senza raccoglierlo in FileInputStream.


Se veramente hai bisogno specificamente di un BufferedInputStream

(Probabilmente no.)
Per citare 269 JEP (sottolineatura mia):

  

Esiste un set ridotto di casi d'uso per inizializzare un'istanza di raccolta mutabile con un set predefinito di valori. Di solito è preferibile avere quei valori predefiniti in una raccolta immutabile e quindi inizializzare la raccolta mutabile tramite un costruttore di copie.


Se vuoi entrambi prepopolare un <=> e aggiungerlo in seguito (perché?), usa

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

o in Java 8 o precedenti:

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

o usando <=>:

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

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

Ma, ancora una volta, è meglio usare direttamente <=> invece di raccoglierlo in <=>.


Programma per interfacce, non per implementazioni

Hai detto di aver dichiarato l'elenco come <=> nel tuo codice, ma dovresti farlo solo se stai usando un membro di <=> che non è in <=>.

Cosa che molto probabilmente non stai facendo.

Di solito dovresti semplicemente dichiarare le variabili dall'interfaccia più generale che intendi utilizzare (ad es. <=>, <=> o <=>) e inizializzarle con l'implementazione specifica (ad es. <=>, < => o <=>).

Altrimenti stai limitando il tuo codice a quel tipo specifico, e sarà più difficile cambiare quando vuoi.

Ad esempio, se si passa da <=> a <=>:

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

Un altro esempio sarebbe sempre dichiarare la variabile un <=> anche se di solito è un <=> o un <=>, perché un giorno presto tu o qualcun altro vorrete usare qualche altro tipo di <=>.

Se hai bisogno di un semplice elenco di dimensioni 1:

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

Se hai bisogno di un elenco di più oggetti:

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

Con Guava puoi scrivere:

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

In Guava ci sono anche altri utili costruttori statici. Puoi leggere su di loro qui .

I letterali della raccolta non sono entrati in Java 8, ma è possibile utilizzare l'API Stream per inizializzare un elenco in una riga piuttosto lunga:

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

Se devi assicurarti che List sia 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, come suggerito in Proposta di miglioramento JDK - 269 , potrebbe essere ottenuto utilizzando letterali da collezione ora come -

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

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

Anche un approccio simile si applicherebbe anche a Map -

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

che è simile a Proposta di raccolta letterali come affermato anche da @coobird. Ulteriori chiarimenti anche nel documento JEP -


Alternative

  

Le modifiche alla lingua sono state prese in considerazione diverse volte e rifiutate:

     

Proposta di moneta del progetto, 29 marzo 2009

     

Proposta di moneta del progetto, 30 marzo 2009

     

Discussione JEP 186 su lambda-dev, gennaio -Marzo 2014

     

La lingua   le proposte sono state accantonate preferibilmente a una proposta basata sulla biblioteca come   riassunto in questo .

Correlato = > Che cos'è il punto di sovraccarico dei metodi di Convenience Factory per le raccolte in Java 9

È possibile creare un metodo di fabbrica:

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

Ma non è molto meglio del tuo primo refactoring.

Per una maggiore flessibilità, può essere generico:

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

In Java 9 possiamo facilmente inizializzare un ArrayList in una sola riga:

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

Questo nuovo approccio di Java 9 presenta molti vantaggi rispetto ai precedenti:

  1. Efficienza spaziale
  2. Immutabilità
  3. Sicuro per thread

Vedi questo post per maggiori dettagli - > Qual è la differenza tra List.of e Arrays.asList?

Con Collezioni Eclipse puoi scrivere quanto segue:

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

Puoi anche essere più specifico sui tipi e se sono mutabili o immutabili.

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

Puoi anche fare lo stesso con Set e Borse:

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: sono un committer per le raccolte Eclipse.

Il modo più compatto per farlo è:

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

Ecco un altro modo:

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

Usa semplicemente il codice seguente come segue.

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

Puoi usare le seguenti istruzioni:

Snippet di codice:

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

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

(Dovrebbe essere un commento, ma troppo lungo, quindi nuova risposta). Come altri hanno già detto, il metodo Arrays.asList è di dimensioni fisse, ma non è l'unico problema. Inoltre non gestisce molto bene l'eredità. Ad esempio, supponiamo di avere quanto segue:

class A{}
class B extends A{}

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

Quanto sopra si traduce in un errore del compilatore, perché List<B> (che è ciò che viene restituito da Arrays.asList) non è una sottoclasse di List<A>, anche se è possibile aggiungere oggetti di tipo B a un oggetto <=> . Per ovviare a questo, devi fare qualcosa del tipo:

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

Questo è probabilmente il modo migliore per farlo, esp. se hai bisogno di un elenco illimitato o devi utilizzare l'ereditarietà.

Come Tom ha detto:

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

Ma poiché ti sei lamentato di volere un ArrayList, dovresti prima sapere che ArrayList è una sottoclasse di List e potresti semplicemente aggiungere questa riga:

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

Tuttavia, ciò potrebbe farti lamentare delle "prestazioni".

In tal caso non ha senso per me, perché, poiché la tua lista è predefinita, non è stata definita come array (poiché la dimensione è nota al momento dell'inizializzazione).E se questa è un'opzione per te:

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

Nel caso in cui non ti interessino le piccole differenze di prestazioni, puoi anche copiare un array in un ArrayList in modo molto semplice:

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

Ok, ma in futuro avrai bisogno di qualcosa di più del semplice nome del luogo, ti servirà anche un codice paese.Supponendo che si tratti ancora di un elenco predefinito che non cambierà mai durante l'esecuzione, è opportuno utilizzare un file enum set, che richiederebbe la ricompilazione se l'elenco dovesse essere modificato in futuro.

enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA}

potrebbe diventare:

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

Le enumerazioni hanno una statica values metodo che restituisce un array contenente tutti i valori dell'enumerazione nell'ordine in cui sono dichiarati, ad esempio:

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

In tal caso immagino che non avresti bisogno del tuo ArrayList.

PS Randyaa ha dimostrato un altro bel modo usando il metodo dell'utilità statica Collezioni.addAll.

Java 9 ha il seguente metodo per creare un elenco immutabile :

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

che può essere facilmente adattato per creare un elenco modificabile, se necessario:

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

Metodi simili sono disponibili per Set e Map.

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

Puoi utilizzare StickyList da Cactoos :

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

Prova con questa riga di codice:

Collections.singletonList(provider)

Sì, con l'aiuto di Array puoi inizializzare l'elenco di array in una riga,

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

In Java, non puoi farlo

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

Come è stato sottolineato, è necessario eseguire un'inizializzazione con doppio controvento:

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

Ma questo potrebbe costringerti ad aggiungere un'annotazione @SuppressWarnings("serial") o generare un UUID seriale che è fastidioso. Inoltre la maggior parte dei formattatori di codice lo scarterà in più istruzioni / righe.

In alternativa puoi farlo

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

ma allora potresti voler fare un @SuppressWarnings("unchecked").

Anche secondo javadoc dovresti essere in grado di farlo:

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

Ma non riesco a farlo compilare con JDK 1.6.

Collections.singletonList(messageBody)

Se avessi bisogno di un elenco di un elemento !

Collezioni proviene dal pacchetto java.util .

Il modo migliore per farlo:

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

Basta creare una funzione che può avere tutti gli elementi che vuoi e chiamarla per aggiungerli in una riga.

Ecco il codice di 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");

Dichiarazione # 65306 &; Sono lo sviluppatore di AbacusUtil.

Per me Arrays.asList () è il migliore e conveniente. Mi piace sempre inizializzare in quel modo. Se sei un principiante nelle Collezioni Java, vorrei che tu riferissi Inizializzazione ArrayList

Perché non creare una semplice funzione di utilità che funzioni in questo modo?

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

quot &; & ll Quot; sta per " elenco letterale " ;.

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

Sto creando un elenco di messageTemplate da un file XML archiviato nel percorso precedente in un contesto statico

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

In realtà, è possibile farlo in una riga:

Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top