Wie kann man in Java von List <Double> in double [] umwandeln?

74

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?

Kamaci
quelle

Antworten:

49

Hohe Leistung - jedes DoubleObjekt umschließt einen einzelnen doubleWert. Wenn Sie alle diese Werte in einem double[]Array speichern möchten, müssen Sie die Sammlung von DoubleInstanzen 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 doubleWerte auspacken .

Andreas Dolk
quelle
Wie wäre es, wenn Sie Ihren Vorschlag zur Leistung mit dem Vorschlag von @Marcelo Hernández Rish vergleichen?
Kamaci
@kamaci Andreas 'Antwort ist optimal.
Marcelo
8
Technisch gesehen ist O (2n) = O (n)
Rohit Pandey,
Ich schlage vor, dies zu vermeiden 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).
user3389669
96

Mit Sie 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:

  • Holen Sie sich die Stream<Double>von der Liste
  • Ordnen Sie jede Doppelinstanz ihrem primitiven Wert zu, was zu a führt DoubleStream
  • Rufen Sie toArray()auf, um das Array zu erhalten.
Alexis C.
quelle
Was ist die Komplexität für Ihre Antwort hinter den Kulissen?
Kamaci
@kamaci Jedes Element der Pipeline wird einmal besucht, also O (n) für eine grundlegende sequentielle Pipeline ( mapgibt einen Lazy Stream zurück, siehe stackoverflow.com/questions/23696317/… ).
Alexis C.
8

Sie können die ArrayUtilsKlasse von commons-lang verwenden, um a double[]von a zu erhalten Double[].

Double[] ds = frameList.toArray(new Double[frameList.size()]);
...
double[] d = ArrayUtils.toPrimitive(ds);
Marcelo
quelle
7

Gemäß Ihrer Frage,

List<Double> frameList =  new ArrayList<Double>();
  1. Zuerst müssen Sie konvertieren , List<Double>um Double[]durch den Einsatz

    Double[] array = frameList.toArray(new Double[frameList.size()]);
    
  2. 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()]));
Praveen
quelle
1
Es ist wichtig zu beachten, dass dies ArrayUtilsTeil der Apache-Bibliothek ist, also kein Standard-Java : org.apache.commons.lang3.ArrayUtils. Aber es ist trotzdem eine gute Lösung.
Brimborium
6

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[]

Harry Lime
quelle
2

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.

Nikhil Nanivadekar
quelle