87

I have a variable like that:

List<Double> frameList =  new ArrayList<Double>();

/* Double elements has added to frameList */

How can I have a new variable has a type of double[] from that variable in Java with high performance?

kamaci
  • 72,915
  • 69
  • 228
  • 366

7 Answers7

120

With , you can do it this way.

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

What it does is :

  • get the Stream<Double> from the list
  • map each double instance to its primitive value, resulting in a DoubleStream
  • call toArray() to get the array.
Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • What is the complexity for your answer behind the scenes? – kamaci Aug 30 '16 at 12:39
  • @kamaci Each element of the pipeline will be visited once, so O(n) for a basic sequential pipeline (`map` returns a lazy stream, see http://stackoverflow.com/questions/23696317/java-8-find-first-element-by-predicate/23696571#23696571). – Alexis C. Sep 10 '16 at 08:13
52

High performance - every Double object wraps a single double value. If you want to store all these values into a double[] array, then you have to iterate over the collection of Double instances. A O(1) mapping is not possible, this should be the fastest you can get:

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

Thanks for the additional question in the comments ;) Here's the sourcecode of the fitting ArrayUtils#toPrimitive method:

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

(And trust me, I didn't use it for my first answer - even though it looks ... pretty similiar :-D )

By the way, the complexity of Marcelos answer is O(2n), because it iterates twice (behind the scenes): first to make a Double[] from the list, then to unwrap the double values.

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
  • how about comparing your suggestion about performance with @Marcelo Hernández Rish's sugesstion? – kamaci May 16 '11 at 19:08
  • @kamaci Andreas' answer is optimal. – Marcelo May 17 '11 at 21:17
  • 8
    Well technically speaking, O(2n) = O(n) – Rohit Pandey Nov 10 '13 at 06:36
  • I suggest to avoid `doubles.get(i)`, although we know that the questioner provided an ArrayList. An approach like this: `double[] tmp = new double[doubles.size()]; int idx = 0; for (Double d : doubles) { tmp[idx] = d; idx++; }` works good for every List (and even Collection). – user3389669 Jan 04 '16 at 18:22
35

Guava has a method to do this for you: double[] Doubles.toArray(Collection<Double>)

This isn't necessarily going to be any faster than just looping through the Collection and adding each Double object to the array, but it's a lot less for you to write.

ColinD
  • 108,630
  • 30
  • 201
  • 202
8

As per your question,

List<Double> frameList =  new ArrayList<Double>();
  1. First you have to convert List<Double> to Double[] by using

    Double[] array = frameList.toArray(new Double[frameList.size()]);
    
  2. Next you can convert Double[] to double[] using

    double[] doubleArray = ArrayUtils.toPrimitive(array);
    

You can directly use it in one line:

double[] array = ArrayUtils.toPrimitive(frameList.toArray(new Double[frameList.size()]));
Gama11
  • 31,714
  • 9
  • 78
  • 100
Praveen
  • 465
  • 5
  • 13
  • 1
    It's important to note that `ArrayUtils` is part of the Apache library, so not standard Java: `org.apache.commons.lang3.ArrayUtils`. But it's a good solution anyway. – brimborium Aug 17 '17 at 15:15
8

You can use the ArrayUtils class from commons-lang to obtain a double[] from a Double[].

Double[] ds = frameList.toArray(new Double[frameList.size()]);
...
double[] d = ArrayUtils.toPrimitive(ds);
Gama11
  • 31,714
  • 9
  • 78
  • 100
Marcelo
  • 11,218
  • 1
  • 37
  • 51
6

You can convert to a Double[] by calling frameList.toArray(new Double[frameList.size()]), but you'll need to iterate the list/array to convert to double[]

Harry Lime
  • 29,476
  • 4
  • 31
  • 37
2

You can use primitive collections from Eclipse Collections and avoid boxing altogether.

DoubleList frameList = DoubleLists.mutable.empty();
double[] arr = frameList.toArray();

If you can't or don't want to initialize a DoubleList:

List<Double> frames = new ArrayList<>();
double[] arr = ListAdapter.adapt(frames).asLazy().collectDouble(each -> each).toArray();

Note: I am a contributor to Eclipse Collections.

Nikhil Nanivadekar
  • 1,152
  • 11
  • 10