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

Posted

技术标签:

【中文标题】将对象数组转换为其原始类型的数组【英文标题】:Converting an array of objects to an array of their primitive types 【发布时间】:2010-10-08 13:00:07 【问题描述】:

如果您有一组具有基本类型(例如字节、整数、字符等)的 Java 对象。有没有一种巧妙的方法可以将其转换为原始类型的数组?尤其是这可以在不必创建新数组并循环遍历内容的情况下完成。

例如,给定

Integer[] array

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

int[] intArray

不幸的是,当我们在 Hibernate 和一些我们无法控制的第三方库之间进行交互时,这是我们必须经常做的事情。这似乎是一个很常见的操作,所以如果没有捷径,我会感到惊讶。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

再一次,Apache Commons Lang 是你的朋友。他们提供ArrayUtils.toPrimitive(),这正是您所需要的。您可以指定如何处理空值。

【讨论】:

【参考方案2】:

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

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]);

如果您的任何元素是null,所有这些都会抛出NullPointerException

【讨论】:

除了Integer::intValue,您还可以使用i -&gt; i(使用拆箱)。 @robinst 而拆箱是编译器为您调用Integer::intValue,那么当方法可用时,为什么还要创建一个新的lambda呢? @Andreas 只是列出另一个选项,您选择哪个是代码风格/个人偏好的问题。我还对这两种方法进行了微基准测试(使用 JMH),它们具有相同的性能。 使用发布的第一个代码 sn-p 给了我一个“不能在静态上下文中使用非静态方法”错误,所以我改为这样做:int[] ints = Arrays.stream(objects).mapToInt(i -&gt; Integer.parseInt(i.toString())).toArray();希望这对任何有同样的问题。如果有人知道更好的方法,请告诉我。 这应该是当今公认的答案。谢谢亚历克斯。【参考方案3】:

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

【讨论】:

关于空值的好点。出于我的目的,如果其中一个条目为空,我会接受引发异常,就像在拆箱对象时引发 NullPointerException 一样。 这个答案在 Java 8 中不再准确,请参阅 Alex's answer。【参考方案4】:

使用Guava:

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

文档:

Arrays.asList(核心 API) Ints.toArray(番石榴)

【讨论】:

【参考方案5】:

特别是可以在不必创建新数组并循环遍历内容的情况下完成此操作。

您不能在 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。

【讨论】:

【参考方案6】:

或者如果你只做一次,就用简单的方法做。但是您还没有谈到 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++;
    

【讨论】:

【参考方案7】:

使用Dollar 很简单:

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

【讨论】:

这似乎不是 Java,至少不是 Java 1.6 或 1.7。 @LorDalCol Dollar 实际上是一个 Java 库 可以将Java方法命名为$!不过,我不认为这是鼓励……【参考方案8】:

这是所有原始类型的通用解决方案

/**
 * Convert Collection to equivalent array of primitive type
 * @param <S> [in] Object type of source collection
 * @param tcls [in] class of the primitive element
 * @param q [in] source collection
 * @return Equivalent Array of tcls-elements, requires cast to "tcls"[]
 */
public static <S> Object asPrimitiveArray(Class<?> tcls, Collection<S> q)

    int n = q.size();
    Object res = Array.newInstance(tcls, n);
    Iterator<S> i = q.iterator();
    int j = 0;
    while (i.hasNext())
    
        Array.set(res, j++, i.next());
    
    return res;


/**
 * Convert Object array to equivalent array of primitive type
 * @param <S> [in] Object type of source array
 * @param tcls [in] class of the primitive element
 * @param s [in] source array
 * @return Equivalent Array of tcls-elements, requires cast to "tcls"[]
 */
public static <S> Object asPrimitiveArray(Class<?> tcls, S[] s)

    return asPrimitiveArray(tcls, Arrays.asList(s));
 

整数到整数的转换

Integer[] a = ...
int[] t = (int[]) asPrimitiveArray(int.class, a);

【讨论】:

以上是关于将对象数组转换为其原始类型的数组的主要内容,如果未能解决你的问题,请参考以下文章

将 Streams 与原始数据类型和相应的包装器一起使用

MongoDB如何将数组中的字段类型从字符串更改为数组并保持原始值

通过重新解释原始字节从一种类型的 numpy 数组转换为另一种类型

JavaScript 新增两个原始数据类型

C++怎么将 CString 转换成 unsigned char 的数组

数组是原始类型还是对象(或完全是其他东西)?