Как мне конвертировать Double[] в double[]?

Я реализую интерфейс, который имеет функциональность, аналогичную таблице, которая может содержать типы объектов. Интерфейс определяет следующую функцию:

double[] getDoubles(int columnIndex);

Я был озадачен тем, что в моей реализации я храню данные таблицы в 2D Object массив (Object[][] data). Когда мне нужно вернуть значения, я хочу сделать следующее (предполагается, что getDoubles() будет вызываться только для столбца, который содержит удваивается, поэтому не будет ClassCastExceptions):

double[] getDoubles(int columnIndex) {
    return (double[]) data[columnIndex];
}

Но - Java не позволяет Object[] быть брошенным в double[], Приведение к Double[] хорошо, потому что Double является объектом, а не примитивом, но мой интерфейс указывает, что данные будут возвращены как double[],

Итак, у меня есть два вопроса:

  1. Есть ли способ получить данные столбца из Object[][] таблицу и вернуть массив примитивов?
  2. Если я изменю интерфейс для возврата Double[]Будет ли какое-либо влияние на производительность?

8 ответов

Решение

К сожалению, вам нужно будет перебрать весь список и распаковать Double если вы хотите преобразовать его в double[],

Что касается производительности, есть некоторое время, связанное с примитивами упаковки и распаковки в Java. Если набор достаточно мал, вы не увидите никаких проблем с производительностью.

Если вы не возражаете против использования сторонней библиотеки, commons-lang имеет тип ArrayUtils с различными методами для манипулирования.

Double[] doubles;
...
double[] d = ArrayUtils.toPrimitive(doubles);

Существует также дополнительный метод

doubles = ArrayUtils.toObject(d);

Изменить: чтобы ответить на остальную часть вопроса. Это потребует некоторых дополнительных затрат, но если массив не очень большой, вам не стоит об этом беспокоиться. Сначала проверьте его, чтобы увидеть, если это проблема, прежде чем рефакторинг.

Реализация метода, о котором вы на самом деле спрашивали, дала бы что-то вроде этого.

double[] getDoubles(int columnIndex) {
    return ArrayUtils.toPrimitive(data[columnIndex]);
}

В Java 8 это одна строка:

Double[] boxed = new Double[] { 1.0, 2.0, 3.0 };
double[] unboxed = Stream.of(boxed).mapToDouble(Double::doubleValue).toArray();

Обратите внимание, что это все еще перебирает исходный массив и создает новый.

Вы можете использовать для каждого цикла, чтобы создать временный массив того же размера, а затем привести каждый отдельный элемент к удвоению, но только в массиве.

ТАК:

double[] tempArray = new double[data[columnIndex].length];
int i = 0;
for(Double d : (Double) data[columnIndex]) {
  tempArray[i] = (double) d;
  i++;
}

Пожалуйста, поправьте меня, если я здесь не прав.

Если вы хотите вернуть double[], вам нужно будет создать new double[], наполни его и верни.

Это может быть хорошим архитектурным решением. Во-первых, не имеет смысла разыгрывать Object[] к Double[]; это не совсем массив Double потому что там может быть Objectв этом тоже. Во-вторых, если вы возвращаете массив напрямую, код пользователя может изменить его и изменить внутреннюю структуру вашего объекта.

Основным воздействием на производительность будет возвращение массива double[], из-за распаковки и стоимости размещения.

Вы можете использовать ArrayUtils для конвертации

Double[] d; // initialise
double[] array = ArrayUtils.toPrimitive(d);

Не нужно зацикливать все данные.

У меня нет ничего, чтобы добавить к реальному вопросу, кроме того, что сказали jjnguy и Эрик Козлов.

Но только примечание: вы упоминаете приведение массива Object к массиву Double. Следующее НЕ будет работать:

Object[] oa=new Object[3];
oa[0]=new Double("1.0");
oa[1]=new Double("2.0");
oa[2]=new Double("3.0");
Double[] da=(Double[])oa;

Последняя строка выдаст исключение приведения класса. Несмотря на то, что каждый элемент массива действительно является Double, массив был создан как массив объектов, а не как массив Double, поэтому приведение является недействительным.

Я бы добавил ответ ArrayUtils и добавил, что документация по автозагрузке1.5 ( через) как бы показывает, что встроенного способа нет:

Не допускается преобразование из типа массива SC[] в тип массива TC[], если не разрешено преобразование, кроме преобразования строки из SC в TC

Другие вопросы по тегам