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?
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.
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 places
nverä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"));
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.
_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.
Stream
sWarum 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 Stream
s 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.
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.
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");
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));
import com.google.common.collect.ImmutableList;
....
List<String> places = ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");
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
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;
}
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:
Weitere Informationen finden Sie in diesem Beitrag. -> Was ist der Unterschied zwischen List.of und Arrays.asList?
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.
Verwenden Sie einfach den folgenden Code wie folgt.
List<String> list = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}};
Hier ist ein anderer Weg:
List<String> values = Stream.of("One", "Two").collect(Collectors.toList());
Der kompakteste Weg, dies zu tun, ist:
Double array[] = { 1.0, 2.0, 3.0};
List<Double> list = Arrays.asList(array);
(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.
Sie können die folgenden Anweisungen verwenden:
String [] arr = {"Sharlock", "Homes", "Watson"};
List<String> names = Arrays.asList(arr);
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.
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 .
List<String> names = Arrays.asList("2","@2234","21","11");
Sie können StickyList
von Cactoos verwenden:
List<String> names = new StickyList<>(
"Scott Fitzgerald", "Fyodor Dostoyevsky"
);
Versuchen Sie es mit dieser Codezeile:
Collections.singletonList(provider)
Ja, mit Hilfe von Arrays können Sie die Array-Liste in einer Zeile initialisieren.
List<String> strlist= Arrays.asList("aaa", "bbb", "ccc");
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.
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.
Collections.singletonList(messageBody)
Benötigen Sie eine Liste von ein Element!
Sammlungen stammen aus dem Java.util -Paket.
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.
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");
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