如何在Java中将List<Double>转换为double[]?

88

我有一个变量:

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

/* Double elements has added to frameList */

在Java中,我如何高效地将一个变量转换为类型为double[]的新变量?

7个回答

123

使用 ,您可以以此方式操作。

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

它的作用是:

  • 从列表中获取Stream<Double>
  • 将每个双精度实例映射到其基本值,生成一个DoubleStream
  • 调用toArray()以获取数组。

你的答案背后的复杂度是什么? - kamaci
@kamaci 每一个管道元素只会被访问一次,因此对于基本的顺序管道来说时间复杂度为O(n)(map返回一个惰性流,请参见https://dev59.com/O2Ag5IYBdhLWcg3wWp3-#23696571)。 - Alexis C.

52

性能高 - 每个Double对象都包装了一个单独的double值。如果您想将所有这些值存储到double[]数组中,那么您必须迭代Double实例的集合。不可能进行O(1)映射,这应该是最快的方法:

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

感谢你在评论中提出的额外问题 ;) 这里是适配的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;
}

(相信我,即使看起来非常相似,我也没有在第一个答案中使用它 :-D)

顺便说一下,Marcelo的答案的复杂度为O(2n),因为它会迭代两次(在幕后):首先从列表中创建Double[],然后再展开double值。


你觉得和 @Marcelo Hernández Rish 的建议相比,性能如何? - kamaci
@kamaci Andreas的回答是最优的。 - Marcelo
9
从技术角度讲,O(2n)等价于O(n)。 - Rohit Pandey
我建议避免使用 doubles.get(i),尽管我们知道提问者提供了一个ArrayList。像这样的方法:double[] tmp = new double[doubles.size()]; int idx = 0; for (Double d : doubles) { tmp[idx] = d; idx++; }适用于每个List(甚至Collection)。 - user3389669

35

9
根据您的问题,
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);
    
您可以直接在一行中使用它:
double[] array = ArrayUtils.toPrimitive(frameList.toArray(new Double[frameList.size()]));

1
需要注意的是ArrayUtils是Apache库的一部分,不属于标准Java库:org.apache.commons.lang3.ArrayUtils。但无论如何使用它都是一个很好的解决方案。 - brimborium

8

你可以使用commons-lang中的ArrayUtils类从Double[]获取double[]

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

6

你可以通过调用frameList.toArray(new Double[frameList.size()])将其转换为Double[],但是需要迭代列表/数组来转换为double[]


2

您可以使用来自Eclipse Collections的原始集合,完全避免装箱。

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

如果您不能或不想初始化一个DoubleList:
List<Double> frames = new ArrayList<>();
double[] arr = ListAdapter.adapt(frames).asLazy().collectDouble(each -> each).toArray();

注意:我是Eclipse Collections的贡献者。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接