Подтвердить что ты не робот

Как преобразовать 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[].

У меня есть два вопроса:

  • Есть ли способ получить данные столбца из таблицы Object[][] и вернуть массив примитивов?
  • Если я изменил интерфейс для возврата double[], будет ли какое-либо влияние на производительность?
4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

doubles = ArrayUtils.toObject(d);

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

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

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

Ответ 3

В Java 8 это однострочный:

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

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

Ответ 4

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

SO:

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

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

Ответ 5

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

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

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

Ответ 6

Мне нечего добавить к реальному вопросу, кроме того, что сказал 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, массив был создан как массив объектов, а не массив парных разрядов, поэтому приведение недействительно.

Ответ 7

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

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

Нет необходимости перебирать все данные.

Ответ 8

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

Нет разрешенного преобразования из типа массива SC [] в тип массива TC [], если нет разрешенных преобразование, отличное от преобразования строк из SC в TC