Ich habe eine solche Variable:
List<Double> frameList = new ArrayList<Double>();
/* Double elements has added to frameList */
Wie kann ich eine neue Variable haben, die einen Typ double[]
von dieser Variablen in Java mit hoher Leistung hat?
Antworten:
Hohe Leistung - jedes Double
Objekt umschließt einen einzelnen double
Wert. Wenn Sie alle diese Werte in einem double[]
Array speichern möchten, müssen Sie die Sammlung von Double
Instanzen durchlaufen . Ein O(1)
Mapping ist nicht möglich, dies sollte das schnellste sein, das Sie bekommen können:
double[] target = new double[doubles.size()];
for (int i = 0; i < target.length; i++) {
target[i] = doubles.get(i).doubleValue(); // java 1.4 style
// or:
target[i] = doubles.get(i); // java 1.5+ style (outboxing)
}
Danke für die zusätzliche Frage in den Kommentaren;) Hier ist der Quellcode der Anpassungsmethode ArrayUtils#toPrimitive
:
public static double[] toPrimitive(Double[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
return EMPTY_DOUBLE_ARRAY;
}
final double[] result = new double[array.length];
for (int i = 0; i < array.length; i++) {
result[i] = array[i].doubleValue();
}
return result;
}
(Und vertrau mir, ich habe es nicht für meine erste Antwort verwendet - obwohl es ... ziemlich ähnlich aussieht :-D)
Übrigens ist die Komplexität der Marcelos-Antwort O (2n), da sie zweimal (hinter den Kulissen) wiederholt wird: zuerst eine Double[]
aus der Liste erstellen, dann die double
Werte auspacken .
doubles.get(i)
, obwohl wir wissen, dass der Fragesteller eine ArrayList bereitgestellt hat. Ein Ansatz wie dieser: double[] tmp = new double[doubles.size()]; int idx = 0; for (Double d : doubles) { tmp[idx] = d; idx++; }
funktioniert gut für jede Liste (und sogar Sammlung).
Mit Java-8Sie können es auf diese Weise tun.
double[] arr = frameList.stream().mapToDouble(Double::doubleValue).toArray(); //via method reference
double[] arr = frameList.stream().mapToDouble(d -> d).toArray(); //identity function, Java unboxes automatically to get the double value
Was es tut ist:
Stream<Double>
von der ListeDoubleStream
toArray()
auf, um das Array zu erhalten.map
gibt einen Lazy Stream zurück, siehe stackoverflow.com/questions/23696317/… ).
Guava hat eine Methode, um dies für Sie zu tun: double [] Doubles.toArray (Collection <Double>)
Dies ist nicht unbedingt schneller als nur das Durchlaufen des Objekts Collection
und das Hinzufügen jedes Double
Objekts zum Array, aber Sie müssen viel weniger schreiben.
Gemäß Ihrer Frage,
List<Double> frameList = new ArrayList<Double>();
Zuerst müssen Sie konvertieren , List<Double>
um Double[]
durch den Einsatz
Double[] array = frameList.toArray(new Double[frameList.size()]);
Als nächstes können Sie Double[]
zu double[]
using konvertieren
double[] doubleArray = ArrayUtils.toPrimitive(array);
Sie können es direkt in einer Zeile verwenden:
double[] array = ArrayUtils.toPrimitive(frameList.toArray(new Double[frameList.size()]));
ArrayUtils
Teil der Apache-Bibliothek ist, also kein Standard-Java : org.apache.commons.lang3.ArrayUtils
. Aber es ist trotzdem eine gute Lösung.
Sie können Double[]
durch Aufrufen in a konvertieren, frameList.toArray(new Double[frameList.size()])
müssen jedoch die Liste / das Array, in die bzw. das konvertiert werden soll, iterierendouble[]
Sie können primitive Sammlungen aus Eclipse-Sammlungen verwenden und das Boxen insgesamt vermeiden.
DoubleList frameList = DoubleLists.mutable.empty();
double[] arr = frameList.toArray();
Wenn Sie a nicht initialisieren können oder wollen DoubleList
:
List<Double> frames = new ArrayList<>();
double[] arr = ListAdapter.adapt(frames).asLazy().collectDouble(each -> each).toArray();
Hinweis: Ich bin ein Mitarbeiter von Eclipse Collections.