Перетворення масиву об’єктів у масив їх примітивних типів


80

Якщо у вас є масив об’єктів Java, які мають примітивний тип (наприклад, Byte, Integer, Char тощо). Чи є акуратний спосіб перетворити його на масив примітивного типу? Зокрема, це можна зробити без необхідності створювати новий масив і перебирати вміст.

Так наприклад, наведено

Integer[] array

який найоптимальніший спосіб перетворити це на

int[] intArray

На жаль, це те, що нам доводиться робити досить часто під час взаємодії між Hibernate та деякими сторонніми бібліотеками, над якими ми не маємо контролю. Здається, це була б досить поширена операція, тому я був би здивований, якщо не буде ярлика.

Спасибі за вашу допомогу!

Відповіді:


40

На жаль, на платформі Java немає нічого, що це робить. До речі, вам також потрібно явно обробляти nullелементи Integer[]масиву (що intви збираєтеся використовувати для них?).


6
Хороший момент щодо нулів. Для моїх цілей я б прийняв викид, якщо один із записів є нульовим, так само, як NullPointerException, коли ви розпаковуєте об'єкт.
Il-Bhima

2
Ця відповідь більше не точна для Java 8, див . Відповідь Алекса .
Робінст,


70

З потоками, представленими в Java 8, це можна зробити:

int[] intArray = Arrays.stream(array).mapToInt(Integer::intValue).toArray();

Однак, в даний час є тільки примітивні потоки для int, longі double. Якщо вам потрібно перетворити на інший примітивний тип, наприклад, byteнайкоротший шлях без зовнішньої бібліотеки - це:

byte[] byteArray = new byte[array.length];
for(int i = 0; i < array.length; i++) byteArray[i] = array[i];

Або цикл for можна замінити потоком, якщо потрібно:

IntStream.range(0, array.length).forEach(i -> byteArray[i] = array[i]);

Все це викине a, NullPointerExceptionякщо є якийсь із ваших елементів null.


2
Замість Integer::intValue, ви також можете використовувати i -> i(що використовує розпаковування).
Робінст,

1
@robinst І розпакування - це компілятор, який закликає Integer::intValueвас, то навіщо створювати нову лямбда-систему, коли метод легко доступний?
Андреас

@Andreas Просто перерахування іншого варіанту, який із них ви виберете - це питання стилю коду / особистих уподобань. Я також мікробенкмаркнув (використовуючи JMH) два підходи, і вони мають однакову ефективність.
Робінст,

Використання першого розміщеного фрагмента коду дало мені помилку "Не можна використовувати нестатичний метод у статичному контексті", тому я замість цього зробив: int[] ints = Arrays.stream(objects).mapToInt(i -> Integer.parseInt(i.toString())).toArray(); сподіваюся, це корисно для тих, хто має ту ж проблему. І якщо хтось знає кращий спосіб, будь ласка, повідомте мене.
Kartik Chugh

Це має бути прийнятою відповіддю сьогодні. Дякую Алекс.
Per Lundberg


3

Зокрема, це можна зробити без необхідності створювати новий масив і перебирати вміст.

Ви не можете перетворити масив Integer на int (тобто ви не можете змінити тип елементів масиву) на Java. Отже, ви або повинні створити новий масив int [] і скопіювати в нього значення об’єктів Integer, або ви можете використовувати адаптер:

class IntAdapter {
    private Integer[] array;
    public IntAdapter (Integer[] array) { this.array = array; }
    public int get (int index) { return array[index].intValue(); }
}

Це може зробити ваш код трохи читабельнішим, і об’єкт IntAdapter буде споживати лише кілька байтів пам’яті. Велика перевага адаптера полягає в тому, що тут ви можете вирішити особливі випадки:

class IntAdapter {
    private Integer[] array;
    public int nullValue = 0;
    public IntAdapter (Integer[] array) { this.array = array; }
    public int get (int index) { 
        return array[index] == null ? nullValue : array[index].intValue();
    }
}

Іншим рішенням є використання Commons Primitive, що містить безліч заздалегідь визначених адаптерів. У вашому випадку перегляньте ListIntList .


2

Або просто зробіть це простим способом, якщо ви збираєтеся зробити це лише один раз. Але ви не говорили про Integer! = Null case.

    //array is the Integer array
    int[] array2 = new int[array.length];
    int i=0;
    for (Integer integer : array) {
        array2[i] = integer.intValue();
        i++;
    }

1

використання Dollar просто, як:

Integer[] array = ...;
int[] primitiveArray = $(array).toIntArray();

6
Здається, це не Java, принаймні не Java 1.6 або 1.7.
Lordalcol

2
@LorDalCol Dollar насправді є бібліотекою Java
Ярослав Заруба

1
Можна назвати метод Java $! Не думаю, що це заохочує, проте ...
Оле ВВ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.