Dies mag eine einfache Frage sein, aber mein erster Versuch schlug überraschenderweise völlig fehl. Ich wollte eine Reihe primitiver Longs nehmen und daraus eine Liste machen, was ich so versuchte:
long[] input = someAPI.getSomeLongs();
List<Long> inputAsList = Arrays.asList(input); //Total failure to even compile!
Was ist der richtige Weg, um dies zu tun?
java
arrays
collections
boxing
Brandon Yarbrough
quelle
quelle
Antworten:
Ich fand es praktisch, Apache Commons Lang ArrayUtils ( JavaDoc , Maven-Abhängigkeit ) zu verwenden.
Es hat auch die umgekehrte API
BEARBEITEN: aktualisiert, um eine vollständige Konvertierung in eine Liste bereitzustellen, wie in Kommentaren und anderen Korrekturen vorgeschlagen.
quelle
Arrays.asList(ArrayUtils.toObject(input))
wahrscheinlich leicht können .List<Long> = Arrays.asList(inputBoxed)
in ihrer Frage enthalten war, fand ich es überflüssig, es zu wiederholen, da ich es für offensichtlich hielt, ich glaube, ich habe mich geirrt ...Seit Java 8 können Sie jetzt Streams dafür verwenden:
quelle
stream
ist Funktion nur definiertint[]
,long[]
unddouble[]
.LongStream.of(arr).boxed()...
.Arrays.stream(arr).boxed().collect(Collectors.toList());
Leider kann dies nur zurückkehrenList<Object>
quelle
hallidave und jpalecek haben die richtige Idee - sie iterieren über ein Array -, nutzen jedoch nicht die Funktionen von
ArrayList
: Da die Größe der Liste in diesem Fall bekannt ist, sollten Sie sie beim Erstellen der Liste angebenArrayList
.Auf diese Weise werden keine unnötigen Arrays erstellt, die nur von den verworfen werden,
ArrayList
weil sie sich als zu kurz herausstellen, und es werden keine leeren "Slots" verschwendet, weilArrayList
der Platzbedarf überschätzt wurde. Wenn Sie der Liste weiterhin Elemente hinzufügen, wird natürlich ein neues Hintergrundarray benötigt.quelle
Ein bisschen ausführlicher, aber das funktioniert:
In Ihrem Beispiel scheint Arrays.asList () die Eingabe als Liste von langen [] Arrays anstelle einer Liste von Longs zu interpretieren. Sicher ein bisschen überraschend. Autoboxing funktioniert in diesem Fall einfach nicht so, wie Sie es möchten.
quelle
Als eine andere Möglichkeit, die Guava Bibliothek bietet dies als
Longs.asList()
, mit ähnlichen Utility - Klassen für die anderen primitiven Typen.quelle
Nein, es gibt keine automatische Konvertierung von einem Array vom primitiven Typ in ein Array ihrer Referenztypen. Das kannst du nur
quelle
Die Frage lautete, wie ein Array in eine Liste umgewandelt werden kann. Die meisten Antworten zeigten bisher, wie eine neue Liste mit demselben Inhalt wie das Array erstellt oder auf Bibliotheken von Drittanbietern verwiesen wird. Es gibt jedoch einfache, integrierte Optionen für diese Art der Konvertierung. Einige von ihnen wurden bereits in anderen Antworten skizziert (z . B. diese ). Ich möchte hier jedoch auf bestimmte Freiheitsgrade für die Implementierung hinweisen und diese ausarbeiten und die potenziellen Vor- und Nachteile sowie Vorbehalte aufzeigen.
Es sind mindestens zwei wichtige Unterscheidungen zu treffen:
Die Optionen werden hier schnell zusammengefasst, und am Ende dieser Antwort wird ein vollständiges Beispielprogramm angezeigt.
Erstellen einer neuen Liste im Vergleich zum Erstellen einer Ansicht des Arrays
Wenn das Ergebnis eine neue Liste sein soll, kann einer der Ansätze aus den anderen Antworten verwendet werden:
Dabei sollten jedoch die Nachteile berücksichtigt werden: Ein Array mit 1000000-
long
Werten belegt ungefähr 8 Megabyte Speicher. Die neue Liste wird auch ungefähr 8 Megabyte belegen. Und natürlich muss beim Erstellen dieser Liste das gesamte Array durchlaufen werden. In vielen Fällen ist das Erstellen einer neuen Liste einfach nicht erforderlich. Stattdessen reicht es aus, eine Ansicht des Arrays zu erstellen :(Eine Implementierung der
toList
Methode finden Sie im Beispiel unten. )Wenn Sie eine Ansicht des Arrays haben, bedeutet dies, dass Änderungen im Array in der Liste sichtbar sind:
Glücklicherweise ist das Erstellen einer Kopie (dh einer neuen Liste, die nicht von Änderungen im Array betroffen ist) aus der Ansicht trivial:
Dies ist eine echte Kopie, die dem entspricht, was mit der oben gezeigten Stream-basierten Lösung erreicht wird.
Erstellen einer veränderbaren oder einer nicht veränderbaren Ansicht
In vielen Fällen ist es ausreichend, wenn die Liste schreibgeschützt ist . Der Inhalt der resultierenden Liste wird häufig nicht geändert, sondern nur an die nachgeschaltete Verarbeitung übergeben, die nur die Liste liest.
Das Zulassen von Änderungen an der Liste wirft einige Fragen auf:
Es ist möglich, eine Listenansicht für das Array zu erstellen, die geändert werden kann . Dies bedeutet, dass Änderungen in der Liste, wie das Festlegen eines neuen Werts für einen bestimmten Index, im Array sichtbar sind.
Es ist jedoch nicht möglich, eine Listenansicht zu erstellen, die strukturell geändert werden kann . Dies bedeutet, dass keine Vorgänge ausgeführt werden können, die sich auf die Größe der Liste auswirken . Dies liegt einfach daran, dass die Größe des zugrunde liegenden Arrays nicht geändert werden kann.
Das folgende MCVE zeigt die verschiedenen Implementierungsoptionen und die möglichen Verwendungsmöglichkeiten der resultierenden Listen:
Die Ausgabe des Beispiels wird hier gezeigt:
quelle
Ein anderer Weg mit Java 8.
quelle
Ich schreibe eine kleine Bibliothek für diese Probleme:
Falls es Sie interessiert, überprüfen Sie es hier .
quelle
Ein anderer Weg mit Java 8.
quelle
Arrays.stream(a).boxed().collect(Collectors.<Long>toList());
Wenn wir die Antworten von Pavel und Tom kombinieren, erhalten wir dies
quelle
Wenn Sie eine ähnliche Semantik wünschen, müssen
Arrays.asList
Sie die Kundenimplementierung vonList
(wahrscheinlich bis) schreiben (oder verwenden)AbstractList
. Sie sollteArrays.asList
ungefähr dieselbe Implementierung haben wie nur Box- und Unbox-Werte.quelle
Sie können transmorph verwenden :
Dies funktioniert auch, wenn die Quelle beispielsweise ein Array von Ints ist.
quelle
Ich weiß, dass diese Frage alt genug ist, aber ... Sie können auch Ihre eigene Konvertierungsmethode schreiben:
Nachdem Sie es mithilfe des statischen Imports eingefügt haben, können folgende Verwendungszwecke auftreten:
oder
quelle
catch (ArrayIndexOutOfBoundsException ex) { /* Finished getting array elements */ }
, Sie sind eine schreckliche Person.Während es möglich ist, eine neue Liste zu erstellen und alle Werte hinzuzufügen (via for-Schleife oder Streams), habe ich an wirklich großen Arrays gearbeitet und eine schlechte Leistung erzielt. Daher habe ich meine eigene benutzerfreundliche primitive Array-Wrapper-Klasse erstellt.
Beispiel:
Erhalten Sie es hier: https://github.com/Sf298/Sauds-Toolbox/blob/master/src/main/java/PrimitiveArrayWrapper/PrimitiveList.java
HINWEIS: Ich habe es noch nicht vollständig getestet. Lassen Sie mich wissen, wenn Sie Fehler / Probleme finden.
quelle
Sie können verwendet werden
LongStream
für diequelle