Frage

Ich möchte eine Liste von Optionen zu Testzwecken erstellen. Anfangs tat ich:

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

Dann Refactoring ich den Code wie folgt:

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

Gibt es einen besseren Weg, dies zu tun?

War es hilfreich?

Lösung

Eigentlich wohl der „beste“ Weg, um den ArrayList zu initialisieren ist die Methode, die Sie geschrieben, da es keine neues List in irgendeiner Art und Weise erstellen benötigt:

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

Der Haken ist, dass es ziemlich viel Typisierung zu diesem list Instanz verweisen erforderlich.

Es gibt Alternativen, wie eine anonyme innere Klasse mit einer Instanz initializer machen (auch als „Doppel-Klammer-Initialisierung“ bekannt):

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

Aber ich bin nicht allzu gern diese Methode, weil, was Sie am Ende mit einer Unterklasse von ArrayList ist, die eine Instanz initializer hat, und diese Klasse erstellt wird, nur ein Objekt zu schaffen - die wie ein wenig scheint nur Overkill mir.

Was wäre schön gewesen war, wenn die Sammlung Literale Vorschlag für Projekt Münze angenommen wurde (es geplant wurde in Java 7 eingeführt werden, aber es ist nicht wahrscheinlich Teil von Java 8 entweder zu sein).

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

Leider wird es Ihnen hier nicht helfen, da es eher eine unveränderliche List initialisieren wird als ein ArrayList, und darüber hinaus, es ist noch nicht verfügbar, wenn es jemals sein wird.

Andere Tipps

Es wäre einfacher, wenn Sie sind einfach es als List erklären - hat es eine Arraylist sein

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

Oder wenn Sie nur ein Element:

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

Dies würde bedeuten, dass places ist unveränderlich (es eine UnsupportedOperationException Ausnahme verursacht zu ändern versucht geworfen werden).

Um eine veränderbare Liste zu machen, die ein konkretes ArrayList sind Sie eine ArrayList aus der unveränderlichen Liste erstellen:

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

Die einfache Antwort

In Java 10, 11, 12 oder später:

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

In Java 9 oder höher:

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

Dies gibt Ihnen eine unveränderliche List, so kann es nicht geändert werden.
Das ist, was man in den meisten Fällen wollen, wo Sie es sind Vorabauffüllen.


Java 8 oder früher:

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

Dies wird Ihnen ein List durch das Array gesichert, so kann es nicht Länge ändern.
Aber man kann List.set nennen, so ist es immer noch wandelbar ist.


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

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

Der statische Import:

import static java.util.Arrays.asList;  

Welche jede moderne IDE wird vorschlagen und automatisch für Sie tun.
Zum Beispiel in IntelliJ IDEA drücken Sie Alt+Enter und wählen Static import method....


Allerdings empfehle ich nicht die Java 9 List.of Verfahren verkürzt wird, weil mit nur of verwirrend wird.
List.of ist schon kurz genug und liest sich gut.


Mit Streams

Warum muss es an ein List sein?
Mit Java 8 oder höher können Sie eine Stream verwenden, die 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"));

Sie können auch von einem Stream zu einem List gehen:

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

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

Aber bevorzugt, benutzen Sie einfach die Stream ohne es zu einem List zu sammeln.


Wenn Sie wirklich müssen spezifisch eine java.util.ArrayList

(Sie wahrscheinlich nicht tun.)
Um Zitat JEP 269 (Hervorhebung von mir):

  

Es gibt einen kleinen Satz Anwendungsfälle für mit einer vorgegebenen Menge von Werten eine veränderbare Sammlung Instanz initialisiert wird. Es ist in der Regel vorzuziehen, diese vordefinierten Werte in einer unveränderlichen Sammlung zu haben, und dann auf die wandelbaren Sammlung über einen Copy-Konstruktor zu initialisieren.


Wenn Sie auf beide vorab ausgefüllt eine ArrayList und hinzufügen, um es danach (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 noch einmal, es ist besser, nur die Stream direkt zu verwenden, anstatt sie zu einem List zu sammeln.


Programm-Schnittstellen, nicht auf Implementierungen

Sie sagen, Sie die Liste als ArrayList im Code deklariert haben, aber man sollte nur das tun, wenn Sie einige Mitglieder ArrayList verwenden, die nicht in List ist.

Was Sie wahrscheinlich nicht tun.

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

Ansonsten sind Begrenzung Sie Ihren Code auf diesen speziellen Typ, und es wird schwieriger sein, zu ändern, wenn Sie wollen.

Zum Beispiel, wenn Sie ein ArrayList zu einem void method(...) vorbei sind:

// 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 weiteres Beispiel wäre immer Variable eine InputStream erklärt, obwohl es in der Regel ein FileInputStream oder ein BufferedInputStream, denn eines Tages bald, was Sie oder jemand wird eine andere Art von InputStream verwenden möchten.

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

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

Wenn Sie eine Liste von mehreren Objekten:

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

Mit Guava Sie schreiben können:

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

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

Sammlung Literale hat es nicht in Java 8, aber es ist möglich, den Stream-API zu verwenden, um eine Liste in einer ziemlich langer Linie zu initialisieren:

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

Wenn Sie müssen sicherstellen, dass Ihr List ist ein ArrayList:

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 vorgeschlagen in JDK Enhancement Proposal - 269 , dies unter Verwendung erreicht werden könnte Sammlung Literalen jetzt als -

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

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

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

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

, die ähnlich Sammlung Literale Vorschlag als auch durch @coobird angegeben. Ferner sind in der JEP doc geklärt und -


Alternativen

  

Sprache ändert mehrmals in Betracht gezogen wurde, und abgelehnt:

     

Projekt Münze Vorschlag, 29. März 2009

     

Projekt Münze Vorschlag, 30. März 2009

     

JEP 186 Diskussion über Lambda-dev Januar -march 2014

     

Die Sprache   Vorschläge wurden beiseite in den Vorzug einer Bibliothek basierenden Vorschlags als   href="http://mail.openjdk.java.net/pipermail/lambda-dev/2014-March/011938.html" in diesem Nachricht.

Einschlägige => Was ist der Punkt überladener Convenience Factory-Methoden für Sammlungen in Java 9

Sie könnten 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 die erste Refactoring.

Für mehr Flexibilität, kann es sein, generic:

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 wir eine ArrayList in einer einzigen Zeile leicht initialisieren können:

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. Unveränderlichkeit
  3. Thread Sicher

Sehen Sie diesen Beitrag für mehr Details ->

Mit Eclipse-Sammlungen Sie die folgende schreiben:

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

Sie können auch etwas konkreter über die Typen und ob sie Mutable oder Immutable.

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

Sie können auch das gleiche 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

über die kompakteste Art und Weise, dies zu tun ist:

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

Hier ist eine andere Art und Weise:

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

Einfach unten Code wie folgt verwenden.

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

Sie können die folgenden Anweisungen verwenden:

Code-Snippet:

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

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

(Sollte ein Kommentar sein, aber zu lang, so neue Antwort). Wie andere erwähnt haben, ist die Arrays.asList Methode eine feste Größe, aber das ist nicht das einzige Problem mit ihm. Sie funktioniert auch nicht Erbe sehr gut. Zum Beispiel: Angenommen, Sie haben die folgende:

class A{}
class B extends A{}

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

Die obigen Ergebnisse in einem Compiler-Fehlern, weil List<B> (das ist das, was von Arrays.asList zurückgegeben wird) nicht eine Unterklasse von List<A> ist, auch wenn Sie Objekte vom Typ B zu einem List<A> Objekt hinzufügen können. Um dies zu umgehen, müssen Sie tun, so etwas wie:

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

Dies ist wahrscheinlich der beste Weg, dies zu gehen zu tun, esp. wenn Sie eine unbegrenzte Liste benötigen oder Vererbung verwenden.

Wie Tom sagte :

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

Aber da du zu wollen, eine Arraylist beschwert, sollten Sie zunächst wissen, dass Arraylist eine Unterklasse von List ist und man konnte einfach diese Zeile hinzufügen:

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

Obwohl, das könnte man von 'Leistung' machen beschweren.

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

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

Falls Sie der kleineren Leistungsunterschiede kümmern sich nicht, dann können Sie auch eine Reihe an einem Arraylist kopieren sehr einfach:

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

Okay, aber in Zukunft müssen Sie ein bisschen mehr als nur die Ortsnamen, müssen Sie ein zu Ländercode. Unter der Annahme, dies ist immer noch eine vordefinierte Liste, die nie dann während der Laufzeit ändern Sie es passend, einen enum Satz zu verwenden, die erneute Kompilierung erforderlich wäre, wenn die Liste benötigt, um in der Zukunft geändert werden.

enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA}

würde:

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

Enum ist eine statische values Methode, die ein Array zurückgibt enthält alle Werte der Enumeration in der Reihenfolge, wie 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 ich denke, Sie würden Ihre Arraylist nicht benötigen.

P. S. Randyaa demonstriert eine weitere gute Möglichkeit, die statische Hilfsmethode mit Collections.addAll .

Java 9 hat die folgende Methode einer unveränderlich Liste zu erstellen:

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

, die leicht angepasst ist, eine veränderbare Liste zu erstellen, falls erforderlich:

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

ähnliche Verfahren sind in Set und Map.

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

Sie können mit StickyList von Cactoos :

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

Versuchen Sie es mit dieser Codezeile:

Collections.singletonList(provider)

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

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

In Java, können Sie nicht tun

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

Wie wurde darauf hingewiesen, müssen Sie eine doppelte Klammer Initialisierung tun:

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

Aber das kann man in Kraft einer Anmerkung @SuppressWarnings("serial") Hinzufügen oder Entfernen eine serielle UUID erzeugen, die lästig ist. Auch die meisten Code Formatierer wird, dass in mehrere Anweisungen / Zeilen auszupacken.

Alternativ können Sie tun,

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

aber dann möchten Sie vielleicht einen @SuppressWarnings("unchecked") tun.

auch nach javadoc sollten Sie in der Lage sein, dies zu tun:

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

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

Collections.singletonList(messageBody)

Wenn Sie bräuchten eine Liste von haben ein Element

Kollektionen ist von java.util Paket.

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 so viele Elemente haben können, wie Sie wollen und nennen es sie in eine Zeile hinzuzufügen.

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 AbacusUtil

Für mich Arrays.asList () ist die beste und bequemste. Ich mag immer so initialisieren. Wenn Sie ein Anfänger in Java Collections sind dann würde Ich mag Sie sich auf Arraylist Initialisierung

Warum nicht eine einfache Nutzenfunktion machen, das dies tut?

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 "wörtliche Liste".

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

Ich bin eine Liste von messageTemplate aus einer XML-Datei im Pfad vor in statischem Kontext gespeichert Erstellen

public final class TemplateStore {

    private TemplateStore(){}

    private static final String [] VERSIONS = {"081"};
    private static final String TEMPLATE_FILE_MASK = "template/EdiTemplates_v%s.xml";
    private static final String ERROR = "Error In Building Edifact Message Template Store";

    public static final List<MessageTemplate> TEMPLATE_LIST = Arrays.stream(VERSIONS)
            .map(version -> TemplateStore.class
                    .getClassLoader().getResourceAsStream(String.format(TEMPLATE_FILE_MASK, version)))
            .map(inputStream -> {
                try {
                    return ((EdiTemplates) JAXBContext.newInstance(EdiTemplates.class).createUnmarshaller()
                            .unmarshal(inputStream)).getMessageTemplate();
                } catch (JAXBException e) {
                    throw new IllegalArgumentException(ERROR, e);
                }})
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
}

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

Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top