将对象数组转换为其原始类型的数组
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();
但是,目前只有 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]);
如果您的任何元素是null
,所有这些都会抛出NullPointerException
。
【讨论】:
除了Integer::intValue
,您还可以使用i -> i
(使用拆箱)。
@robinst 而拆箱是编译器为您调用Integer::intValue
,那么当方法可用时,为什么还要创建一个新的lambda呢?
@Andreas 只是列出另一个选项,您选择哪个是代码风格/个人偏好的问题。我还对这两种方法进行了微基准测试(使用 JMH),它们具有相同的性能。
使用发布的第一个代码 sn-p 给了我一个“不能在静态上下文中使用非静态方法”错误,所以我改为这样做:int[] ints = Arrays.stream(objects).mapToInt(i -> 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);
【讨论】:
以上是关于将对象数组转换为其原始类型的数组的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB如何将数组中的字段类型从字符串更改为数组并保持原始值
通过重新解释原始字节从一种类型的 numpy 数组转换为另一种类型