У меня есть такая переменная:
List<Double> frameList = new ArrayList<Double>();
/* Double elements has added to frameList */
Как я могу получить новую переменную типа double[]
из этой переменной в Java с высокой производительностью?
У меня есть такая переменная:
List<Double> frameList = new ArrayList<Double>();
/* Double elements has added to frameList */
Как я могу получить новую переменную типа double[]
из этой переменной в Java с высокой производительностью?
Высокая производительность - каждый объект 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)
Кстати, сложность ответа Марселоса - O (2n), потому что он выполняет итерацию дважды (за кадром): сначала сделайте double[]
из списка, затем разверните значения Double
.
С java-8, вы можете сделать это так.
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()
, чтобы получить массив.Guava имеет способ сделать это для вас: double [] Doubles.toArray(Collection <Double> )
Это не обязательно будет быстрее, чем просто цикл через Collection
и добавление каждого объекта Double
к массиву, но это намного меньше для вас.
Вы можете использовать класс ArrayUtils
из commons-lang, чтобы получить double[]
из Double[]
.
Double[] ds = frameList.toArray(new Double[frameList.size()]);
...
double[] d = ArrayUtils.toPrimitive(ds);
Вы можете преобразовать в Double[]
, вызвав frameList.toArray(new Double[frameList.size()])
, но вам нужно будет перебирать список/массив для преобразования в Double[]
По вашему вопросу,
List<Double> frameList = new ArrayList<Double>();
Сначала вы должны преобразовать List<Double>
в Double[]
, используя
Double[] array = frameList.toArray(new Double[frameList.size()]);
Далее вы можете конвертировать Double[]
в double[]
используя
double[] doubleArray = ArrayUtils.toPrimitive(array);
Вы можете напрямую использовать его в одной строке:
double[] array = ArrayUtils.toPrimitive(frameList.toArray(new Double[frameList.size()]));
Вы можете использовать примитивные коллекции из 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.