将对象数组转换为其原始类型的数组


80

如果您有一个具有原始类型(例如Byte,Integer,Char等)的Java对象数组。有没有一种巧妙的方法可以将其转换为原始类型的数组?特别是可以做到这一点,而不必创建新的数组并遍历内容。

因此,例如

Integer[] array

将其转换为最简洁的方法是什么

int[] intArray

不幸的是,在Hibernate和我们无法控制的某些第三方库之间进行接口时,这是我们经常要做的事情。看来这将是一个非常普通的操作,所以如果没有捷径,我会感到惊讶。

谢谢你的帮助!

Answers:


40

不幸的是,Java平台中没有任何东西可以做到这一点。顺便说一句,您还需要显式处理数组中的null元素Integer[](这些元素int将用于什么?)。


6
关于空值的要点。出于我的目的,如果条目之一为null,则我将接受引发异常,与将对象拆箱时引发NullPointerException的方式相同。
Il-Bhima

2
该答案在Java 8中不再准确,请参见Alex的答案
罗宾斯特


69

使用Java 8中引入的,可以做到这一点:

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

然而,目前只有基本流intlongdouble。如果您需要转换为其他原始类型(例如,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


2
除了Integer::intValue,您还可以使用i -> i(使用拆箱)。
罗宾斯特

1
@robinst编译器会要求Integer::intValue您取消装箱,那么,如果该方法随时可用,为什么还要创建一个新的lambda?
安德烈亚斯

@Andreas仅列出了另一个选项,您选择的是一个代码风格/个人喜好问题。我还对这两种方法进行了微基准测试(使用JMH),它们具有相同的性能。
罗宾斯特

使用发布的第一个代码段给我一个“在静态上下文中不能使用非静态方法”错误,所以我改为: int[] ints = Arrays.stream(objects).mapToInt(i -> Integer.parseInt(i.toString())).toArray(); 希望这对遇到相同问题的任何人都有用。如果有人知道更好的方法,请告诉我。
Kartik Chugh

这应该是当今公认的答案。谢谢亚历克斯。
Per Lundberg


3

特别是可以做到这一点,而不必创建新的数组并遍历内容。

您不能在Java中将Integer数组转换为int(即,您不能更改数组元素的类型)。因此,您必须创建一个新的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 Primitives,它包含许多预定义的适配器。在您的情况下,请查看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库
JaroslavZáruba2015年

1
可以命名Java方法$!我认为这并不令人鼓舞……
Ole VV
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.