new - java static arraylist




Initialisierung einer ArrayList in einer Zeile (20)

Die einfache Antwort

In Java 8 oder früher:

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

Dadurch erhalten Sie eine vom Array gestützte List , sodass die Länge nicht geändert werden kann.
Sie können jedoch List.set , also ist es noch veränderbar.

In Java 9:

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

Dadurch erhalten Sie eine unveränderliche List , die nicht geändert werden kann.
Welches ist es, was Sie in den meisten Fällen wollen, wenn Sie es vorher ausfüllen.

Die kürzere Antwort

Sie können Arrays.asList mit einem statischen Import noch kürzer machen:

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

Der statische Import:

import static java.util.Arrays.asList;  

Was jede moderne IDE vorschlagen und automatisch für Sie tun wird.
In IntelliJ IDEA drücken Sie beispielsweise Alt+Enter und wählen die Static import method... .

Ich empfehle jedoch nicht, die Java 9 List.of Methode zu verkürzen, da es nur verwirrend wird.
List.of ist bereits kurz genug und liest sich gut.

Stream s verwenden

Warum muss es eine List ?
Mit Java 8 oder höher können Sie einen Stream der flexibler ist:

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

Sie können Stream s verketten:

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

Oder Sie können von einem Stream zu einer List :

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

Verwenden Sie jedoch vorzugsweise den Stream ohne ihn in einer List zu sammeln.

Wenn Sie wirklich eine java.util.ArrayList benötigen

(Sie wahrscheinlich nicht.)
Um JEP 269 (Hervorhebung meines) zu zitieren:

Es gibt eine kleine Anzahl von Anwendungsfällen zum Initialisieren einer veränderlichen Sammlungsinstanz mit einer vordefinierten Menge von Werten. Es ist normalerweise vorzuziehen, diese vordefinierten Werte in einer unveränderlichen Auflistung zu speichern und die veränderliche Auflistung dann über einen Kopierkonstruktor zu initialisieren.

Wenn Sie eine ArrayList sowohl vorab auffüllen als auch später hinzufügen möchten (warum?), Verwenden Sie

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

oder in Java 9:

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

oder mit Stream :

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

Es ist jedoch besser, den Stream direkt zu verwenden, anstatt ihn in einer List sammeln.

Programmieren Sie zu Schnittstellen, nicht zu Implementierungen

Sie sagten, Sie haben die Liste in Ihrem Code als ArrayList deklariert. Sie sollten dies jedoch nur tun, wenn Sie ein Mitglied der ArrayList , das nicht in List .

Was Sie wahrscheinlich nicht tun.

Normalerweise sollten Sie Variablen nur durch die allgemeinste Schnittstelle deklarieren, die Sie verwenden werden (z. B. Iterable , Collection oder List ), und sie mit der jeweiligen Implementierung (z. B. ArrayList , LinkedList oder Arrays.asList() ) Arrays.asList() .

Ansonsten beschränken Sie Ihren Code auf diesen bestimmten Typ, und es ist schwieriger, ihn zu ändern, wenn Sie möchten.

Zum Beispiel:

// Iterable if you just need iteration, for (String s : strings):
Iterable<String> strings = new ArrayList<>();   

// Collection if you also need .size() or .stream():
Collection<String> strings = new ArrayList<>(); 

// List if you also need .get(index):
List<String> strings = new ArrayList<>();       

// Don't declare a specific list implementation
// unless you're sure you need it:
ArrayList<String> strings = new ArrayList<>();  // You don't need ArrayList

Ein anderes Beispiel wäre, die Variable immer als InputStream zu deklarieren, obwohl es sich in der Regel um einen FileInputStream oder einen BufferedInputStream , da Sie oder eine andere FileInputStream eines Tages einen anderen InputStream möchten.

Ich möchte eine Liste von Optionen zu Testzwecken erstellen. Zuerst habe ich das gemacht:

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

Dann habe ich den Code folgendermaßen überarbeitet:

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

Gibt es einen besseren Weg, dies zu tun?


(Sollte ein Kommentar sein, aber zu lang, so neue Antwort). Wie bereits erwähnt, hat die Arrays.asList Methode eine feste Größe, dies ist jedoch nicht das einzige Problem. Es geht auch nicht gut mit Vererbung um. Angenommen, Sie haben Folgendes:

class A{}
class B extends A{}

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

Das obige Ergebnis führt zu einem Compiler-Fehler, da List<B> (was von Arrays.asList zurückgegeben wird) keine Unterklasse von List<A> , obwohl Sie Objekte des Typs B zu einem List<A> -Objekt hinzufügen können . Um dies zu umgehen, müssen Sie Folgendes tun:

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

Dies ist wahrscheinlich der beste Weg, dies zu tun, besonders. wenn Sie eine unbegrenzte Liste benötigen oder Vererbung verwenden müssen.


Der kompakteste Weg, dies zu tun, ist:

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

Eigentlich ist es möglich, es in einer Zeile zu machen:

Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})

Für mich ist Arrays.asList () die beste und bequemste. Ich möchte immer so initialisieren. Wenn Sie Anfänger in Java Collections sind, möchte ich Sie auf die ArrayList-Initialisierung verweisen


Hier ist der Code von 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");

Erklärung: Ich bin der Entwickler von AbacusUtil.


In Java 9 können wir eine ArrayList einfach in einer einzigen Zeile initialisieren:

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

oder

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

Dieser neue Ansatz von Java 9 bietet gegenüber den vorherigen viele Vorteile:

  1. Raumeffizienz
  2. Immutability
  3. Fadensicher

In diesem Beitrag finden Sie weitere Informationen -> Was ist der Unterschied zwischen List.of und Arrays.asList?


In Java ist das nicht möglich

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

Wie bereits erwähnt, müssen Sie eine doppelte Klammer-Initialisierung durchführen:

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

Dies kann Sie jedoch dazu zwingen, eine Anmerkung @SuppressWarnings("serial") hinzuzufügen oder eine serielle UUID zu generieren, die störend ist. Auch die meisten Code-Formatierer entpacken das in mehrere Anweisungen / Zeilen.

Alternativ können Sie das auch tun

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

Dann möchten Sie jedoch ein @SuppressWarnings("unchecked") .

Laut Javadoc sollten Sie dazu auch in der Lage sein:

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

Aber ich kann es nicht mit JDK 1.6 kompilieren.


Java 9 hat die folgende Methode zum Erstellen einer unveränderlichen Liste:

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

die leicht angepasst werden kann, um bei Bedarf eine veränderliche Liste zu erstellen:

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

Ähnliche Methoden stehen für Set und Map .


Mit Guava Sie schreiben:

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

In Guava gibt es auch andere nützliche statische Konstruktoren. Sie können hier darüber lesen.


Mit Java 9 , wie in JDK Enhancement Proposal - 269 vorgeschlagen , könnte dies mit Sammelliteralen jetzt als - erreicht werden.

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

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

Ein ähnlicher Ansatz würde auch für Map gelten -

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

Dies ist ähnlich wie der Vorschlag von Collection Literals, wie von @coobird angegeben. Weitere Klarstellung auch im JEP-Dokument -

Alternativen

Sprachänderungen wurden mehrmals berücksichtigt und abgelehnt:

Vorschlag für Projektmünzen, 29. März 2009

Vorschlag für Projektmünzen, 30. März 2009

JEP 186-Diskussion zu Lambda-dev, Januar-März 2014

Die Sprachvorschläge wurden einem bibliotheksbasierten Angebot vorgezogen, wie in dieser message.

Lesen Sie weiter => Was ist der Punkt überladener Convenience Factory-Methoden für Sammlungen in Java 9?


Sammlungsliterale haben es nicht in Java 8 geschafft, aber es ist möglich, die Stream-API zu verwenden, um eine Liste in einer ziemlich langen Zeile zu initialisieren:

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

Wenn Sie sicherstellen müssen, dass Ihre List eine ArrayList :

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

Sie können die folgenden Anweisungen verwenden:

Code-Auszug:

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

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

Sie können eine Factory-Methode erstellen:

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

Aber es ist nicht viel besser als dein erstes Refactoring.

Für mehr Flexibilität kann es generisch sein:

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

Versuchen Sie es mit dieser Codezeile:

Collections.singletonList(provider)

Verwenden Sie einfach den folgenden Code wie folgt.

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

Wenn Sie eine einfache Liste von Größe 1 benötigen:

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

Wenn Sie eine Liste mit mehreren Objekten benötigen:

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

Wie Tom sagte :

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

Da Sie sich jedoch beschwert haben, eine ArrayList gewünscht zu haben, sollten Sie zunächst wissen, dass ArrayList eine Unterklasse von List ist, und Sie können einfach diese Zeile hinzufügen:

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

Das kann Sie jedoch dazu bringen, sich über "Leistung" zu beklagen.

In diesem Fall macht es für mich keinen Sinn, da Ihre Liste vordefiniert ist, wurde sie nicht als Array definiert (da die Größe zum Zeitpunkt der Initialisierung bekannt ist). Und wenn das eine Option für Sie ist:

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

Wenn Sie sich nicht für die geringfügigen Leistungsunterschiede interessieren, können Sie ein Array auch ganz einfach in eine ArrayList kopieren:

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

Okay, aber in Zukunft benötigen Sie etwas mehr als nur den Ortsnamen, Sie benötigen auch eine Landesvorwahl. Angenommen, es handelt sich immer noch um eine vordefinierte Liste, die sich während der Laufzeit niemals ändert. Dann ist es angebracht, ein enum verwenden, das eine erneute Kompilierung erfordert, wenn die Liste in der Zukunft geändert werden muss.

enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA}

würde werden:

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

Aufzählungen haben eine statische values Methode, die ein Array zurückgibt, das alle Werte der Aufzählung in der angegebenen Reihenfolge enthält, z. B .:

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

In diesem Fall brauchen Sie wahrscheinlich Ihre ArrayList nicht.

PS Randyaa demonstrierte mit der statischen Utility-Methode Collections.addAll weiteren schönen Weg.


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

import com.google.common.collect.ImmutableList;

....

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




initialization