Преобразование массива объектов в массив их примитивных типов


Если у вас есть массив объектов Java, которые имеют примитивный тип (например, Byte, Integer, Char и т. д.). Есть ли изящный способ я могу преобразовать его в массив примитивного типа? В частности, это можно сделать без необходимости создавать новый массив и перебирать содержимое.

Так, например, учитывая

Integer[] array

каков самый аккуратный способ преобразовать это в

int[] intArray

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

Спасибо за вашу помощь!

7 64

7 ответов:

к сожалению, в платформе Java нет ничего, что делает это. Кстати, вам также нужно явно обрабатывать null элементов Integer[] массив (что int вы собираетесь использовать для них?).

еще раз Apache Commons Lang - твой друг. Они обеспечивают ArrayUtils.toPrimitive () что делает именно то, что вам нужно. Вы можете указать, как вы хотите обрабатывать значения null.

С потоки введен в 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]);

все это будет бросать NullPointerException если любой из ваших элементов null.

используя гуавы:

int[] intArray = Ints.toArray(Arrays.asList(array));

документы:

в частности, это может быть сделано без необходимости создавать новый массив и цикл через содержимое.

вы не можете преобразовать массив Integer в int (т. е. вы не можете изменить тип элементов массива) в Java. Таким образом, вы либо должны создать новый массив int[] и скопировать в него значение целочисленных объектов, либо вы можете использовать адаптер:

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 Primitives который содержит множество предопределенных адаптеров. В вашем случае, взгляните на ListIntList.

или просто сделать это легко, если вы будете делать это только один раз. Но вы еще не говорили о Integer!=null случай.

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

С помощью доллар - это просто:

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