3312 Stimmen

Initialisierung einer ArrayList in einer Zeile

Ich wollte eine Liste von Optionen zu Testzwecken erstellen. Zuerst habe ich dies getan:

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 umstrukturiert:

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

Gibt es eine bessere Möglichkeit, dies zu tun?

43 Stimmen

Wenn dies für Unit-Tests gedacht ist, sollten Sie Groovy einmal ausprobieren. Sie können Ihren Testcode in Groovy schreiben, während Sie Java-Code testen, und mit ArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]

5 Stimmen

In Java SE 7 können Sie den parametrisierten Typ des Konstruktors durch eine leere Menge von Typparametern (<>) ersetzen: Map<String, List<String>> myMap = new HashMap<>();

2 Stimmen

2680voto

Tom Punkte 41119

Einfacher wäre es, wenn Sie es einfach als List - 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 places es unveränderlich (der Versuch, sie zu ändern, führt zu einer UnsupportedOperationException ausgelöste Ausnahme).

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

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

2229voto

coobird Punkte 155882

Tatsächlich ist es wahrscheinlich der "beste" Weg, die Initialisierung der ArrayList ist die Methode, die Sie geschrieben haben, denn sie muss keine neue List in irgendeiner Weise:

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

Der Haken an der Sache ist, dass man ziemlich viel tippen muss, um sich auf diese list Instanz.

Es gibt Alternativen, wie z. B. die Erstellung einer anonymen inneren Klasse mit einem Instanzinitialisierer (auch bekannt als "Doppelklammerinitialisierung"):

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

Ich bin jedoch nicht sehr angetan von dieser Methode, weil man am Ende eine Unterklasse von ArrayList die einen Instanzinitialisierer hat, und diese Klasse wird nur erstellt, um ein Objekt zu erstellen - das scheint mir einfach ein bisschen übertrieben zu sein.

Es wäre schön gewesen, wenn die Sammlung Literale Vorschlag für Projekt Münze wurde akzeptiert (es sollte in Java 7 eingeführt werden, aber es ist unwahrscheinlich, dass es auch in Java 8 enthalten sein wird):

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

Leider wird es Ihnen hier nicht helfen, da es eine unveränderliche List und nicht eine ArrayList und außerdem ist es noch nicht verfügbar, wenn es überhaupt jemals verfügbar sein wird.

1130voto

Die einfache Antwort

Java 9 oder höher:

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

Dadurch erhalten Sie eine unveränderlich List Sie kann also nicht geändert werden.
Das ist das, was Sie in den meisten Fällen wollen, wenn Sie es vorbesetzen.

Java 8 oder früher:

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

Dadurch erhalten Sie eine List * durch ein Array unterstützt, so dass es seine Länge nicht ändern kann.
Aber Sie können anrufen List.set(...) also ist es immer noch änderbar .

* Einzelheiten der Durchführung: Es ist eine private verschachtelte Klasse innerhalb von <code>java.util.Arrays</code> genannt. <code>ArrayList</code> ,<br>die eine andere Klasse ist als <code>java.util.ArrayList</code> obwohl ihre einfachen Namen die gleichen sind.

Statische Einfuhr

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

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

Jede moderne IDE * wird dies für Sie vorschlagen und tun.

Ich empfehle nicht den statischen Import der List.of Methode als nur of weil es verwirrend ist.

* In IntelliJ IDEA drücken Sie zum Beispiel <code>Alt+Enter</code> und wählen Sie <code>Static import method...</code>

Verwendung von Stream s

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

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

Sie können verketten Stream s:

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

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

import static java.util.stream.Collectors.toList;
...
var strings = Stream.of("foo", "bar", "baz").toList(); // Java 16

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

Verwenden Sie aber vorzugsweise nur die Stream ohne sie zu sammeln zu einem List .

Wenn Sie speziell eine java.util.ArrayList *

Wenn Sie möchten, dass beide eine Vorauswahl treffen ArrayList et nachträglich hinzuzufügen, verwenden Sie

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

oder in Java 8 oder früher:

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

oder mit Stream :

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

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

Aber auch hier ist es besser, einfach die Stream direkt, anstatt sie in einer List .

* Sie brauchen wahrscheinlich nicht speziell eine <code>ArrayList</code> . Um zu zitieren <a href="http://openjdk.java.net/jeps/269" rel="noreferrer">GEP 269 </a>:

Es gibt eine <strong>kleiner Satz </strong>von Anwendungsfällen für die Initialisierung einer veränderlichen Sammlungsinstanz mit einem vordefinierten Satz von Werten. Normalerweise ist es besser, diese vordefinierten Werte in einer unveränderlichen Sammlung zu haben und dann die veränderliche Sammlung über einen Kopierkonstruktor zu initialisieren.

(Hervorhebung von mir)

Auf Schnittstellen programmieren, nicht auf Implementierungen

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

Was Sie höchstwahrscheinlich nicht tun.

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

Andernfalls schränken Sie Ihren Code auf diesen speziellen Typ ein, und es wird schwieriger, ihn zu ändern, wenn Sie es wollen.

Wenn Sie zum Beispiel eine ArrayList zu einer 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 random access, .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, eine Variable immer als InputStream auch wenn es sich in der Regel um eine FileInputStream oder eine BufferedInputStream denn eines Tages werden Sie oder jemand anderes eine andere Art von Werkzeug verwenden wollen. InputStream .

122voto

Randyaa Punkte 2905

Wenn Sie eine einfache Liste der 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");

66voto

Paweł Adamski Punkte 3005

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 über sie lesen aquí .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X