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

问题描述 投票:0回答:10

如果您有一个具有基本类型(例如 Byte、Integer、Char 等)的 Java 对象数组。有没有一种巧妙的方法可以将其转换为原始类型的数组?特别是,无需创建新数组并循环内容即可完成此操作。

例如,给定

Integer[] array

将其转换为最巧妙的方法是什么

int[] intArray

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

感谢您的帮助!

java arrays primitive-types
10个回答
93
投票

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


81
投票

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

如果您的任何元素是

NullPointerException
,所有这些都会抛出
null


39
投票

不幸的是,Java 平台中没有任何东西可以做到这一点。顺便说一句,您还需要显式处理

null
数组中的
Integer[]
元素(您要使用什么
int
来处理这些元素?)。


27
投票

使用番石榴

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

文档:


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 的情况。

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

0
投票

使用美元很简单:

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

0
投票

我们可以使用

Stream
API 从盒装对象对应项创建原始类型数组。

对于

Character[]
数组转换为
char[]
,使用相应大小分配的自定义
Collector
,以及
Supplier<CharBuffer>
BiConsumer<CharBuffer, Character>
累加器、
BinaryOperator<CharBuffer>
组合器和
Function<CharBuffer, char[]>
整理器),如下所示:

Collector<Character, CharBuffer, char[]> charArrayCollector = Collector.of(
  () -> CharBuffer.allocate(95), 
  CharBuffer::put, 
  CharBuffer::put, 
  CharBuffer::array
);

它为可打印的 ASCII 字符提供

CharBuffer
,将每个流式字符累积到 CharBuffer 实例中,以正确的顺序组合来自多个 CharBuffer 实例的并行处理结果,最后根据累积和组合的结果构建所需的
char[]
数组,之后所有线程都已完成。

首先,我们从标准可打印 ASCII 集创建一个

Character[]
测试数组,利用
int
中的
IntStream
值,迭代 ASCII 范围并将每个值映射到字符
Stream
,之后将它们转换为
char
原语并将其转换为
Character
对象:

Character[] asciiCharacters = IntStream.range(32, 127)
  .mapToObj(i -> Character.valueOf((char)i))
  .toArray(Character[]::new);

现在,我们只需从

Stream
数组创建一个
Character
字符,然后可以由自定义收集器将其收集到
char[]
数组中。

char[] asciiChars = Stream.of(asciiCharacters ).collect(charArrayCollector);

这适用于其他

Number
类型:

byte[] bytes = new byte[] { Byte.MIN_VALUE, -1 , 0, 1, Byte.MAX_VALUE };
Byte[] boxedBytes = IntStream.range(0, bytes.length)
  .mapToObj(i -> bytes[i])
  .toArray(Byte[]::new);
byte[] collectedBytes = Stream.of(boxedBytes).collect(
  Collector.of(
    () -> ByteBuffer.allocate(boxedBytes.length), 
    ByteBuffer::put, 
    ByteBuffer::put, 
    ByteBuffer::array
  )
);

short[] shorts = new short[] { Short.MIN_VALUE, -1, 0, 1, Short.MAX_VALUE };
Short[] boxedShorts = IntStream.range(0, shorts.length)
  .mapToObj(i -> shorts[i])
  .toArray(Short[]::new);
short[] collectedShorts = Stream.of(boxedShorts).collect(
  Collector.of(
    () -> ShortBuffer.allocate(boxedShorts .length), 
    ShortBuffer::put, 
    ShortBuffer::put, 
    ShortBuffer::array
  )
);

float[] floats = new float[] { Float.MIN_VALUE, -1.0f, 0f, 1.0f, Float.MAX_VALUE };
Float[] boxedFLoats = IntStream.range(0, floats.length)
  .mapToObj(i -> floats[i])
  .toArray(Float[]::new);
float[] collectedFloats = Stream.of(boxedFLoats).collect(
  Collector.of(
    () -> FloatBuffer.allocate(boxedFLoats.length), 
    FloatBuffer::put, 
    FloatBuffer::put, 
    FloatBuffer::array
  )
);

Stream
API 支持的原始类型可以更容易地转换:

int[] ints = new int[] { Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE };
Integer[] integers = IntStream.of(ints).boxed().toArray(Integer[]::new);
int[] collectedInts = Stream.of(integers).collect(
  Collector.of(
    () -> IntBuffer.allocate(integers.length), 
    IntBuffer::put, 
    IntBuffer::put, 
    IntBuffer::array
  )
);

long[] longs = new long[] { Long.MIN_VALUE, -1l, 0l, 1l, Long.MAX_VALUE };
Long[] boxedLongs = LongStream.of(longs).boxed().toArray(Long[]::new);
long[] collectedLongs = Stream.of(boxedLongs ).collect(
  Collector.of(
    () -> LongBuffer.allocate(boxedLongs .length), 
    LongBuffer::put, 
    LongBuffer::put, 
    LongBuffer::array
  )
);

double[] doubles = new double[] { Double.MIN_VALUE, -1.0, 0, 1.0, Double.MAX_VALUE };
Double[] boxedDoubles = DoubleStream.of(doubles)
  .boxed()
  .toArray(Double[]::new);
double[] collectedDoubles = Stream.of(boxedDoubles).collect(
  Collector.of(
    () -> DoubleBuffer.allocate(boxedDoubles.length), 
    DoubleBuffer::put, 
    DoubleBuffer::put, 
    DoubleBuffer::array
  )
);

-1
投票

是的,我们可以将对象数组转换为原始数组,请参考下面的代码。 Java 8 非常适合更详细地学习 Java 8 技能,我有一个 YouTube 频道。

https://www.youtube.com/@thefullstackguy 快乐学习:)

private static int[] reverseJava8(int[] arr) {
    Object[] objects = Arrays.stream(arr)
            .boxed()
            .sorted(Comparator.reverseOrder())
            .toArray();
    return Arrays.stream(objects).mapToInt(i -> (int) i).toArray();

}

-1
投票

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

/**
 * Convert Collection to equivalent array of primitive type
 * @param <S> [in] Element 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] Element 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));
} 

对于整数到 int 的转换

Integer[] a = ...
int[] t = (int[]) asPrimitiveArray(int.class, a);
© www.soinside.com 2019 - 2024. All rights reserved.