Ich wollte 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 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?
java
collections
arraylist
initialization
Makrig
quelle
quelle
ArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]
Antworten:
Wahrscheinlich
ArrayList
ist die von Ihnen geschriebene Methode die "beste" Methode zum Initialisieren der Methode, da sieList
in keiner Weise eine neue erstellen muss :Der Haken ist, dass einiges an Eingabe 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 "Double-Brace-Initialisierung" bezeichnet):
Ich mag diese Methode jedoch nicht besonders, da Sie am Ende eine Unterklasse haben,
ArrayList
die einen Instanzinitialisierer hat, und diese Klasse nur erstellt wird, um ein Objekt zu erstellen - das scheint mir nur ein bisschen übertrieben zu sein.Was schön gewesen wäre, wäre, wenn der Vorschlag für Sammlungsliterale für Project Coin angenommen worden wäre (er sollte in Java 7 eingeführt werden, ist aber wahrscheinlich auch nicht Teil von Java 8.):
Leider hilft es Ihnen hier nicht weiter, da es
List
eher eine unveränderliche als eine initialisiertArrayList
und darüber hinaus noch nicht verfügbar ist, falls dies jemals der Fall sein wird.quelle
Es wäre einfacher, wenn Sie es einfach als
List
- deklarieren müssten, muss es eine ArrayList sein?Oder wenn Sie nur ein Element haben:
Dies würde bedeuten , dass
places
ist unveränderlich (versucht es eine verursacht zu ändernUnsupportedOperationException
Ausnahme ausgelöst werden).Um eine veränderbare Liste zu
ArrayList
erstellen, die konkret ist , können SieArrayList
aus der unveränderlichen Liste eine erstellen :quelle
ArrayList
es besser, die Deklaration in zu ändern , wenn Sie keine spezifischen Methoden verwendenList
. Geben Sie Schnittstellen an, keine Implementierungen.asList(...)
eine feste Größe zurückgegebenList
, die bei mutierenden Vorgängen wieremove
undclear
, Dinge, die derList
Vertrag zu unterstützen behauptet, in die Luft sprengt . Selbst wenn Sie die Deklaration als belassen habenList
, müssen Sie sie verwendenList l = new ArrayList(asList(...))
, um ein Objekt zu erhalten, das keine OperationNotSupported-Ausnahmen auslöst. Liskov Substitutionsprinzip jemand?remove
undclear
sind optionale Operationen inList
,asList(...)
folgen also dem Vertrag. Nirgendwo sagt das OP, dass er später weitere Elemente hinzufügen muss. Das Beispiel ist nur ein Beispiel, dasList
mit drei Elementen initialisiert werden muss.Die einfache Antwort
In Java 9 oder höher wurde danach
List.of()
hinzugefügt:Mit Java 10 oder höher kann dies mit dem
var
Schlüsselwort gekürzt werden .Dies gibt Ihnen eine unveränderliche
List
, so dass es nicht geändert werden kann.Welches ist, was Sie in den meisten Fällen wollen, in denen Sie es vorab ausfüllen.
Java 8 oder früher:
Dadurch erhalten Sie eine
List
Unterstützung durch ein Array, sodass die Länge nicht geändert werden kann.Aber du kannst anrufen
List.set
, also ist es immer noch veränderlich .Arrays.asList
Mit einem statischen Import können Sie noch kürzer machen :Der statische Import:
Was jede moderne IDE vorschlägt und automatisch für Sie erledigt.
Zum Beispiel drücken Sie in IntelliJ IDEA
Alt+Enter
und wählenStatic import method...
.Ich empfehle jedoch nicht, die
List.of
Methode auf zu verkürzenof
, da dies verwirrend wird.List.of
ist schon kurz genug und liest sich gut.Mit
Stream
sWarum muss es ein sein
List
?Mit Java 8 oder höher können Sie ein
Stream
flexibleres verwenden:Sie können
Stream
s verketten :Oder Sie können von a
Stream
nach a gehenList
:Verwenden Sie das Gerät jedoch vorzugsweise,
Stream
ohne es zu sammelnList
.Wenn Sie wirklich speziell eine brauchen
java.util.ArrayList
(Wahrscheinlich nicht.)
Um JEP 269 zu zitieren (Hervorhebung von mir):
Wenn Sie möchten sowohl vorab ausgefüllt ein
ArrayList
und fügen Sie danach (warum?), Nutzungoder in Java 8 oder früher:
oder mit
Stream
:Aber auch hier ist es besser, das
Stream
direkt zu verwenden, als es zu einem zu sammelnList
.Programmieren Sie auf Schnittstellen, nicht auf Implementierungen
Sie sagten, Sie hätten die Liste als
ArrayList
in Ihrem Code deklariert , aber Sie sollten dies nur tun, wenn Sie ein Mitglied verwendenArrayList
, das nicht in enthalten istList
.Was Sie höchstwahrscheinlich nicht tun.
Normalerweise sollten Sie nur Variablen deklarieren durch die allgemeinste Schnittstelle , die Sie verwenden möchten (zB
Iterable
,Collection
oderList
) und initialisieren sie mit der konkreten Umsetzung (zBArrayList
,LinkedList
oderArrays.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 übergebenvoid method(...)
:Ein anderes Beispiel wäre, immer eine Variable zu deklarieren,
InputStream
obwohl es normalerweise eineFileInputStream
oder eine istBufferedInputStream
, weil Sie oder jemand anderes eines Tages bald eine andere Art von verwenden möchtenInputStream
.quelle
Arrays.asList
ist eine statische Methode. Siehe docs.oracle.com/javase/1.5.0/docs/guide/language/…Wenn Sie eine einfache Liste der Größe 1 benötigen:
Wenn Sie eine Liste mit mehreren Objekten benötigen:
quelle
Mit Guava können Sie schreiben:
In Guava gibt es auch andere nützliche statische Konstruktoren. Sie können über sie lesen hier .
quelle
java.util.Arrays
wieList<String> names = Arrays.asList("Beckah", "Sam", "Michael");
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:
Wenn Sie müssen sicherstellen , dass Ihr
List
eine istArrayList
:quelle
Mit Java-9und höher, wie in JEP 269: Convenience Factory-Methoden für Sammlungen vorgeschlagen , könnte dies mit Sammlungsliteralen erreicht werden, die jetzt mit -
Ein ähnlicher Ansatz würde auch gelten für
Map
-Dies ähnelt dem von @coobird angegebenen Vorschlag für Sammlungsliterale . Weiter im JEP geklärt -
Alternativen
Verwandte Themen: Was ist der Sinn überladener Convenience Factory-Methoden für Sammlungen in Java 9?
quelle
quelle
Collections.unmodifiableList(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"))
, das wirdunmodifiableList(asList("Buenos Aires", "Córdoba", "La Plata"))
mit statischen Importen. Sie benötigen dafür keine Google-Sammlungen.ImmutableList
an andere Methoden weitergeben, die a benötigenList
, und dann haben Sie diese Dokumentation trotzdem verloren.Sie können eine Factory-Methode erstellen:
Aber es ist nicht viel besser als dein erstes Refactoring.
Für mehr Flexibilität kann es generisch sein:
quelle
In Java 9 können wir ein einfach
ArrayList
in einer einzelnen Zeile initialisieren :oder
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?
quelle
Der kompakteste Weg, dies zu tun, ist:
quelle
Verwenden Sie einfach den folgenden Code wie folgt.
quelle
Mit Eclipse Collections können Sie Folgendes schreiben:
Sie können auch genauer festlegen, welche Typen veränderlich oder unveränderlich sind.
Sie können dasselbe auch mit Sets und Taschen tun:
Hinweis: Ich bin ein Committer für Eclipse-Sammlungen.
quelle
Hier ist ein anderer Weg:
quelle
(Sollte ein Kommentar sein, aber zu lang, also neue Antwort). Wie andere bereits erwähnt haben, hat die
Arrays.asList
Methode eine feste Größe, aber das ist nicht das einzige Problem. Es geht auch nicht sehr gut mit Vererbung um. Angenommen, Sie haben Folgendes:Das Obige führt zu einem Compilerfehler, da
List<B>
(was von Arrays.asList zurückgegeben wird) keine Unterklasse von istList<A>
, obwohl Sie einemList<A>
Objekt Objekte vom Typ B hinzufügen können . Um dies zu umgehen, müssen Sie Folgendes tun:Dies ist wahrscheinlich der beste Weg, dies zu tun, insb. Wenn Sie eine unbegrenzte Liste benötigen oder Vererbung verwenden müssen.
quelle
Sie können die folgenden Anweisungen verwenden:
Code-Auszug:
quelle
letters = Arrays.asList(new String[]{"A", "B", "C"});
Wie Tom sagte :
Da Sie sich jedoch darüber beschwert haben, eine ArrayList zu wollen, sollten Sie zunächst wissen, dass ArrayList eine Unterklasse von List ist, und Sie können einfach diese Zeile hinzufügen:
Dies könnte Sie jedoch dazu bringen, sich über die Leistung zu beschweren.
In diesem Fall macht es für mich keinen Sinn, warum Ihre Liste, da sie vordefiniert ist, nicht als Array definiert wurde (da die Größe zum Zeitpunkt der Initialisierung bekannt ist). Und wenn das eine Option für Sie ist:
Wenn Sie sich nicht um die geringfügigen Leistungsunterschiede kümmern, können Sie ein Array auch ganz einfach in eine ArrayList kopieren:
Okay, aber in Zukunft brauchen Sie ein bisschen mehr als nur den Ortsnamen, Sie brauchen auch einen Ländercode. Angenommen, dies ist immer noch eine vordefinierte Liste, die sich zur Laufzeit nie ändert, dann ist es angebracht, einen
enum
Satz zu verwenden, der neu kompiliert werden muss, wenn die Liste in Zukunft geändert werden muss.würde werden:
Aufzählungen 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.In diesem Fall würden Sie Ihre ArrayList wohl nicht benötigen.
PS Randyaa demonstrierte einen anderen guten Weg mit der statischen Dienstprogrammmethode Collections.addAll .
quelle
Java 9 verfügt über die folgende Methode zum Erstellen einer unveränderlichen Liste:
die leicht angepasst werden kann, um bei Bedarf eine veränderbare Liste zu erstellen:
Ähnliche Methoden stehen für
Set
und zur VerfügungMap
.quelle
quelle
Ja, mit Hilfe von Arrays können Sie die Array-Liste in einer Zeile initialisieren.
quelle
Sie können
StickyList
von Cactoos verwenden :quelle
Versuchen Sie es mit dieser Codezeile:
quelle
In Java ist das nicht möglich
Wie bereits erwähnt, müssen Sie eine doppelte Klammerinitialisierung durchführen:
Dies kann Sie jedoch dazu zwingen, eine Anmerkung hinzuzufügen
@SuppressWarnings("serial")
oder eine serielle UUID zu generieren, was ärgerlich ist. Außerdem werden die meisten Code-Formatierer dies in mehrere Anweisungen / Zeilen auspacken.Alternativ können Sie tun
aber dann möchten Sie vielleicht eine machen
@SuppressWarnings("unchecked")
.Auch laut Javadoc sollten Sie dazu in der Lage sein:
Aber ich kann es nicht mit JDK 1.6 kompilieren.
quelle
Wenn Sie eine Liste mit einem Artikel benötigen !
Sammlungen stammen aus dem Paket java.util .
quelle
Der beste Weg, es zu tun:
Erstellen Sie einfach eine Funktion, die beliebig viele Elemente enthalten kann, und rufen Sie sie auf, um sie in einer Zeile hinzuzufügen.
quelle
Object
.Hier ist Code von AbacusUtil
Erklärung: Ich bin der Entwickler von AbacusUtil.
quelle
Für mich ist Arrays.asList () die beste und bequemste. Ich initialisiere immer gerne so. Wenn Sie ein Anfänger in Java-Sammlungen sind, möchte ich, dass Sie auf die ArrayList-Initialisierung verweisen
quelle
add()
Methoden?Warum nicht eine einfache Utility-Funktion erstellen, die dies tut?
"
ll
" steht für "wörtliche Liste".quelle
Interessanterweise ist kein Einzeiler mit der anderen überladenen
Stream::collect
Methode aufgeführtquelle
Eigentlich ist es möglich, dies in einer Zeile zu tun:
quelle