Erläutern Sie die Syntax von Sammlungen. <String> emptyList ()

70

Ich habe gerade über generische Programmierung, die List<E>Schnittstelle und studiert ArrayList, damit ich die folgende Aussage verstehen kann.

ArrayList<String> list = new ArrayList<String>();

Aber ich verstehe die nächste Aussage, die ich beim Surfen im Internet gesehen habe, nicht.

List<String> list2 = Collections.<String>emptyList();
  1. Was ist Collections? Warum ist es nicht Collections<E>oder Collections<String>?
  2. Warum steht <String>vor dem Methodennamen emptyList?

(Ist nicht emptyList<String>()korrekt für Generic?)

  1. Was bedeutet die Aussage?
Jenix
quelle
Collectionsist eine Java-Klasse.
PM 77-1
39
Dies ist eine absolut gültige Frage . Ich bin mir nicht sicher, ob es so hart behandelt wurde. Für jemanden, der statische Methodengenerika nicht versteht, könnte dies eine verwirrende Aussage sein. Abstimmung zur Wiedereröffnung.
Qix - MONICA wurde am
3
Auch für die Wiedereröffnung gestimmt. Der Titel der Frage ist wahrscheinlich zu weit gefasst, aber die eigentliche Frage im Körper ist ziemlich spezifisch. Vielleicht ist das Bearbeiten des Titels besser als das Schließen.
TM.
3
Mir scheint, dass die Anzahl der Konzepte, die zur Beantwortung dieser Frage erklärt werden müssen, so hoch ist, dass eine Antwort fast ein Java-Einführungs-Tutorial darstellen würde. Aber hier ist meine Erklärung der generischen Methoden . Lesen Sie zu Frage 2 Informationen zu statischen Importen.
Chris Martin
2
@ChrisMartin Siehe gegebene Antworten. Sie scheinen einen ziemlich guten Job zu machen. OP versteht Generika, aber Methodengenerika sind ein (verständlicherweise) neues Konzept, das in der Natur nicht so verbreitet ist.
Qix - MONICA wurde am

Antworten:

58

Diese Zeile erstellt eine leere Liste von Zeichenfolgen, indem eine statische Methode mit einem generischen Typparameter aufgerufen wird.

Innerhalb der CollectionsKlasse gibt es eine statische Methode emptyList, die wie folgt deklariert ist:

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

Dies hat einen generischen Typparameter T. Wir nennen call this method mit:

List<String> list = Collections.emptyList();

und Twird Stringaufgrund der Art von als gefolgert list.

Wir können den Typ auch angeben, Tindem wir ihn beim Aufruf in spitze Klammern setzen emptyList. Dies kann erforderlich sein, wenn wir einen spezifischeren Typ wünschen, als abgeleitet wird:

List<? extends Object> list = Collections.<String>emptyList();

emptyList<String>()ist nicht korrekt, da diese Platzierung nur gültig ist, wenn Instanzen generischer Klassen erstellt werden und keine Methoden aufgerufen werden. Bei Verwendung newgibt es zwei mögliche Typparameter, die vor dem Klassennamen nur für den Konstruktor und die nach dem Klassennamen für die gesamte Instanz, also für die Klasse:

class MyClass<A> {
    public <B> MyClass(A a, B b) {
        System.out.println(a + ", " + b);
    }
}

Wir können seinen Konstruktor nennen, wo Aist Stringund Bist Integerwie:

MyClass<String> a = new <Integer>MyClass<String>("a", 3);

oder durch Verwendung der Typinferenz:

MyClass<String> a = new MyClass<>("a", 3);

Siehe auch:

fgb
quelle
4
Vielleicht möchten Sie erwähnen, dass Collectionses sich bei einer dieser Klassen nur um statische Methoden handelt. Es ist nicht dazu gedacht, selbst instanziiert zu werden (und kann es auch nicht sein).
Qix - MONICA wurde am
Ich bin kein Java - Experte , aber es scheint mir, dann, das foo<T>()ist nicht überhaupt „einen Konstruktor aufrufen“, obwohl die resultierende Objekt Konstruktion führt zu einem Aufruf von foo‚s - Konstruktor (unter alle anderen Schritte a zu instanziiert genommen foo) . Dann gibt es keine tatsächliche Inkonsistenz oder Diskrepanz mit der generischen Methodenaufrufsyntax <T>bar()(die aus einem C ++ - Hintergrund stammt und sehr seltsam ist, lassen Sie mich einfach sagen!).
Leichtigkeitsrennen im Orbit
9
Ich habe die Konstruktorsyntax überprüft, und es stellt sich heraus, dass Konstruktoren auch ihre eigenen Typparameter haben können, sodass wir eine Syntax haben können, die zwei Typparameterausdrücke wie enthält new <String>MyClass<Integer>(2).
FGB
@fgb Huh ... das ist neu. Ich glaube, ich habe so etwas noch nie in freier Wildbahn gesehen. Interessant!
Qix - MONICA wurde am
"emptyList <String> () ist nicht korrekt, da diese Platzierung nur beim Aufrufen von Konstruktoren gültig ist, nicht bei statischen Methoden." Diese Anweisung ist verwirrend. Da es sich bei dieser Frage um generische Methoden handelt, scheint es, als würden Sie über generische Konstruktoren sprechen. Aber du bist nicht. SomeClass<String>()dient zum Erstellen einer Instanz einer generischen Klasse mit einem nicht generischen Konstruktor. Um eine Instanz einer Klasse mit einem generischen Konstruktor zu erstellen, würden Sie so etwas tun new <String> SomeClass().
Newacct
11

Was ist Collections? Warum ist es nicht Collections<E>oder Collections<String>?

Collections ist eine JDK-Klasse.

Diese Klasse besteht ausschließlich aus statischen Methoden, die Sammlungen bearbeiten oder zurückgeben. Es enthält polymorphe Algorithmen, die mit Sammlungen arbeiten, "Wrapper", die eine neue Sammlung zurückgeben, die von einer bestimmten Sammlung unterstützt wird, und einige andere Kleinigkeiten.

Es ist nicht generisch und kann nicht instanziiert werden.

Warum steht <String>vor dem Methodennamen emptyList?

Collections#emptyListist eine generische Methode. Hier geben wir explizit ein Typargument an String.

(Ist nicht emptyList<String>()korrekt für Generic?)

Nein, in Java stehen generische Typargumente für Methoden vor dem Methodennamen.

Was bedeutet die Aussage?

Wir rufen die statische emptyListMethode auf und weisen ihren Rückgabewert einer Variablen vom Typ zu List<String>.

Sotirios Delimanolis
quelle
9

Kurz gesagt, dies erstellt eine leere, unveränderliche Liste von Zeichenfolgen.

Schauen wir uns den Ausdruck Stück für Stück an.

Collectionsist der Name einer Klasse. Aus dem Javadoc :

Diese Klasse besteht ausschließlich aus statischen Methoden, die Sammlungen bearbeiten oder zurückgeben. Es enthält polymorphe Algorithmen, die mit Sammlungen arbeiten, "Wrapper", die eine neue Sammlung zurückgeben, die von einer bestimmten Sammlung unterstützt wird, und einige andere Kleinigkeiten.

emptyList()ist der Name einer statischen Methode, die in der CollectionsKlasse ( Javadoc ) definiert ist. Es ist eine generische Methode, und das <String>in Collections.<String>emptyList()gibt das generische Typargument an.

Die Methode gibt a zurück List<T>, in diesem Fall List<String>: eine Liste von Zeichenfolgen. Insbesondere wird eine leere , unveränderliche Liste von Zeichenfolgen zurückgegeben.

NPE
quelle
+1zum Hervorheben (obwohl in den Dokumenten vorhanden) der Unveränderlichkeit der zurückgegebenen Sammlung.
6

1.Sammlung ist eine Schnittstelle und Sammlungen sind eine statische Klasse, die ausschließlich aus statischen Methoden besteht, die Sammlungen bearbeiten oder zurückgeben. Daher können wir nicht verwenden Collections<E>oder Collections<String>.

2. <String>before emptyList (wird verwendet, um die leere Liste abzurufen, die unveränderlich ist) gibt an, dass nur String-Werte hinzugefügt werden können. Mögen:

list2.add("A");
list2.add("B");

3.Die Anweisung bedeutet, dass eine unveränderliche leere Liste vom Typ Liste erstellt wird.

Sie können diesen Link überprüfen: Unterschied zwischen Java Collection und Collections

Löwe
quelle
2
denotes that only String values can be added to it.Eine genauere Beschreibung lautet: Sie deklariert den Parametertyp der Methode als String, sodass der Rückgabewert eine homogene Liste von Strings ist.
nhahtdh
6

Erstens Collectionshandelt es sich um eine Hilfsbibliothek statischer Methoden, die mit verschiedenen Arten von Sammlungen arbeiten. Wenn Sie irgendeine Art von C ++ - Programmierung durchgeführt haben, ist dies ein Synonym für die <algorithm>Funktionsbibliothek.

In diesem Fall rufen Sie die statische Methode auf emptyList(), die eine leere Liste eines bestimmten Typs zurückgibt. Da für diese Methoden immer noch ein Typ erforderlich ist, Collectionsdie Methoden jedoch auf viele Typen verweisen können, müssen Sie den Typ beim Aufruf angeben.

Um eine generische Methode aufzurufen , müssen Sie sie mit der Parameterliste (dh <String>) vor dem Methodennamen, aber nach dem Punkt aufrufen .

List<String> someList = Collections.<String>emptyList();
Qix - MONICA WURDE FEHLERHAFT
quelle