it-swarm.com.de

Initialisierung einer ArrayList in einer Zeile

Ich möchte eine Liste mit 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 wie folgt überarbeitet:

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

Gibt es einen besseren Weg, dies zu tun?

2551
Macarse

Der wahrscheinlich "beste" Weg, die ArrayList zu initialisieren, ist die von Ihnen geschriebene Methode, da keine neue List erstellt werden muss:

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

Der Haken ist, dass einiges an Tipparbeit erforderlich ist, um auf diese list -Instanz zu verweisen.

Es gibt Alternativen, z. B. das Erstellen einer anonymen inneren Klasse mit einem Instanzinitialisierer (auch als "doppelte geschweifte Klammer" bezeichnet):

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

Ich mag diese Methode jedoch nicht besonders, da Sie am Ende eine Unterklasse von ArrayList haben, die einen Instanzinitialisierer hat, und diese Klasse nur zum Erstellen eines Objekts erstellt wird - das scheint nur ein bisschen bisschen übertrieben für mich.

Nizza wäre gewesen, wenn der Vorschlag Sammlungsliteratur für Projektmünze angenommen worden wäre (er sollte in Java 7 eingeführt werden, ist es aber nicht wahrscheinlich auch Teil von Java 8.):

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

Leider hilft es Ihnen hier nicht weiter, da es ein unveränderliches List anstelle eines ArrayList initialisiert und außerdem noch nicht verfügbar ist, falls dies jemals der Fall sein sollte.

1890
coobird

Es wäre einfacher, wenn Sie es einfach als List deklarieren würden - muss es eine ArrayList sein?

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

Oder wenn Sie nur ein Element haben:

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

Dies würde bedeuten, dass placesnveränderlich ist (der Versuch, es zu ändern, führt dazu, dass eine UnsupportedOperationException -Ausnahme ausgelöst wird).

Um eine veränderbare Liste zu erstellen, die ein konkretes ArrayList ist, können Sie aus der unveränderlichen Liste ein ArrayList erstellen:

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

Die einfache Antwort

In Java 10, 11, 12 oder höher:

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

In Java 9 oder höher:

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

Dadurch erhalten Sie ein unveränderliches List, sodass es nicht geändert werden kann.
Was ist das, was Sie in den meisten Fällen wollen, in denen Sie es vorbelegen.


Java 8 oder früher:

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

Dadurch erhalten Sie ein List, das vom Array unterstützt wird, sodass die Länge nicht geändert werden kann.
Aber Sie können _List.set_ anrufen, es ist also immer noch veränderlich.


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 jedes moderne IDE vorschlägt und automatisch für Sie erledigt.
Zum Beispiel drücken Sie in IntelliJ IDEA _Alt+Enter_ und wählen _Static import method..._ aus.


Ich empfehle jedoch nicht, die Methode Java 9 _List.of_ zu kürzen, da es verwirrend wird, nur of zu haben.
_List.of_ ist schon kurz genug und liest sich gut.


Mit Streams

Warum muss es ein List sein?
Mit Java 8 oder höher können Sie ein Stream verwenden, das flexibler ist:

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

Sie können Streams verketten:

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

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

_import static Java.util.stream.Collectors.toList;

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

Verwenden Sie jedoch vorzugsweise einfach Stream, ohne es in List zu sammeln.


Wenn Sie wirklich speziell einen _Java.util.ArrayList_ brauchen

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

Es gibt eine kleine Menge 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 haben und dann die veränderbare Auflistung über einen Kopierkonstruktor zu initialisieren.


Wenn Sie beide ein ArrayList vorbelegen und danach hinzufügen möchten (warum?), Verwenden Sie

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

oder in Java 8 oder früher:

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

oder mit Stream:

_import static Java.util.stream.Collectors.toCollection;

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

Aber auch hier ist es besser, das Stream direkt zu verwenden, anstatt es in einem List zu sammeln.


Programmieren Sie auf Schnittstellen, nicht auf Implementierungen

Sie sagten, Sie hätten die Liste in Ihrem Code als ArrayList deklariert, aber Sie sollten dies nur tun, wenn Sie ein Mitglied von ArrayList verwenden, das nicht in List enthalten ist.

Was du höchstwahrscheinlich nicht tust.

Normalerweise sollten Sie Variablen nur über die allgemeinste Schnittstelle deklarieren, die Sie verwenden möchten (z. B. Iterable, Collection oder List), und sie mit der spezifischen Implementierung initialisieren (z. B. ArrayList, LinkedList oder Arrays.asList()).

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

Wenn Sie beispielsweise ein ArrayList an ein void method(...) übergeben:

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

Ein anderes Beispiel wäre, die Variable immer als InputStream zu deklarieren, auch wenn es sich normalerweise um FileInputStream oder BufferedInputStream handelt, weil Sie oder jemand anderes eines Tages bald eine andere Art von InputStream.

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

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

Wenn Sie eine Liste mehrerer Objekte benötigen:

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

Mit Guave können 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 darüber lesen hier .

55
Paweł Adamski

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 Ihr List ein ArrayList ist:

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

....

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

Mit Java 9, wie in JDK Enhancement Proposal - 269 vorgeschlagen, kann dies erreicht werden, indem Sammlungsliterale jetzt als - verwendet 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 ähnelt Vorschlag für Sammlungsliteratur , wie auch von @coobird angegeben. Weitere Erläuterungen finden Sie auch in der JEP-Dokumentation.


Alternativen

Sprachänderungen wurden mehrfach berücksichtigt und abgelehnt:

Projektmünzvorschlag, 29. März 2009

Projektmünzvorschlag, 30. März 2009

JEP 186 Diskussion über Lambda-Dev, Januar-März 2014

Die Sprachvorschläge wurden einem bibliotheksbasierten Vorschlag vorgezogen, wie in dieser Nachricht zusammengefasst

Related => Wozu überladene Convenience Factory-Methoden für Sammlungen in Java 9

23
Naman

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 Ihr erstes Refactoring.

Für eine größere 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;
}
22
Jordão

In Java 9 können wir einfach ein ArrayList in einer einzelnen 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 hat viele Vorteile gegenüber den vorherigen:

  1. Space Efficiency
  2. nveränderlichkeit
  3. Thread Safe

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

15
Mohit Tyagi

Mit Eclipse Collections können Sie Folgendes schreiben:

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

Sie können auch genauer festlegen, welche Typen und ob sie veränderlich oder unveränderlich sind.

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

Dasselbe können Sie auch mit Sets und Taschen tun:

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

Hinweis: Ich bin ein Committer für Eclipse-Sammlungen.

8
Donald Raab

Verwenden Sie einfach den folgenden Code wie folgt.

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

Hier ist ein anderer Weg:

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

Der kompakteste Weg, dies zu tun, ist:

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

(Sollte ein Kommentar sein, aber zu lang, also neue Antwort). Wie bereits erwähnt, hat die Methode Arrays.asList eine feste Größe, aber das ist nicht das einzige Problem. Vererbung wird auch nicht sehr gut verarbeitet. Angenommen, Sie haben Folgendes:

class A{}
class B extends A{}

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

Das oben Gesagte führt zu einem Compilerfehler, da List<B> (was von Arrays.asList zurückgegeben wird) keine Unterklasse von List<A> ist, obwohl Sie einem List<A>-Objekt Objekte vom Typ B 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. Wenn Sie eine unbegrenzte Liste benötigen oder die Vererbung verwenden müssen.

6
user439407

Sie können die folgenden Anweisungen verwenden:

Code-Auszug:

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

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

Java 9 hat die folgende Methode, um eine nveränderliche Liste zu erstellen:

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

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

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

Ähnliche Methoden sind für Set und Map verfügbar.

5

Wie Tom sagte :

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

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

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

Das könnte Sie allerdings über "Leistung" beschweren.

In diesem Fall macht es für mich keinen Sinn, warum, da Ihre Liste vordefiniert ist, sie nicht als Array definiert wurde (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 um die geringen Leistungsunterschiede kümmern, können Sie auch ganz einfach ein Array in eine ArrayList kopieren:

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

Okay, aber in Zukunft brauchen Sie ein bisschen mehr als nur den Ortsnamen, Sie brauchen auch eine Landesvorwahl. Angenommen, es handelt sich immer noch um eine vordefinierte Liste, die sich zur Laufzeit nicht ändern wird, dann ist es angemessen, einen enum -Satz zu verwenden, der eine Neukompilierung erfordert, wenn die Liste in 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;
    }
}

Enums haben eine statische values -Methode, die ein Array zurückgibt, das alle Werte der Aufzählung in der Reihenfolge enthält, in der sie deklariert sind, z.

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

In diesem Fall würden Sie vermutlich Ihre ArrayList nicht benötigen.

P.S. Randyaa demonstriert ein weiterer netter Weg mit der statischen Utility-Methode Collections.addAll .

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

Sie können StickyList von Cactoos verwenden:

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

Versuchen Sie es mit dieser Codezeile:

Collections.singletonList(provider)
3
Ant20

Ja, mit Hilfe von Arrays können Sie die Array-Liste in einer Zeile initialisieren.

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

In Java geht das nicht

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

Wie bereits erwähnt, müssten Sie eine doppelte geschweifte Klammer initialisieren:

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 ärgerlich ist. Auch die meisten Code-Formatierer packen das in mehrere Anweisungen/Zeilen aus.

Alternativ können Sie tun

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

aber dann möchten Sie vielleicht eine @SuppressWarnings("unchecked") ausführen.

Auch laut javadoc solltest du dazu in der Lage sein:

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

Aber ich bin nicht in der Lage, es mit JDK 1.6 zu kompilieren.

2
Dawg

Der beste Weg, es zu tun:

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

Erstellen Sie einfach eine Funktion, die beliebig viele Elemente enthalten kann, und rufen Sie sie auf, um sie in einer Zeile hinzuzufügen.

1
Elegant Odoo
Collections.singletonList(messageBody)

Benötigen Sie eine Liste von ein Element!

Sammlungen stammen aus dem Java.util -Paket.

1
ViliusK

Hier ist 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.

1
user_3380739

Warum nicht eine einfache Utility-Funktion erstellen, die dies erledigt?

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

"ll" steht für "Literal List".

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

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

0
Manoj Kumar