例如,给定以下数组:
Integer[] array
最简单的方法是将此内容转换为什么?
int[] intArray
不幸的是,当我们在Hibernate和一些我们无法控制的第三方库之间进行接口操作时,我们必须经常这样做。看起来这应该是一个非常常见的操作,所以如果没有快捷方式,我会感到惊讶。
谢谢你的帮助!
Integer[] array
最简单的方法是将此内容转换为什么?
int[] intArray
不幸的是,当我们在Hibernate和一些我们无法控制的第三方库之间进行接口操作时,我们必须经常这样做。看起来这应该是一个非常常见的操作,所以如果没有快捷方式,我会感到惊讶。
谢谢你的帮助!
再次提醒,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];
IntStream.range(0, array.length).forEach(i -> byteArray[i] = array[i]);
如果您的元素中有任何一个是 null
,所有这些操作都会抛出 NullPointerException
。
很遗憾,在Java平台上没有任何东西可以做到这一点。另外,您还需要明确处理Integer []
数组中的null
元素(对于它们使用什么int
?)。
int[] intArray = Ints.toArray(Arrays.asList(array));
文档:
Arrays.asList
(核心API)Ints.toArray
(Guava)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();
}
}
如果你只需要执行一次,那么可以采用简单的方法。但是你没有提到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++;
}
我们可以使用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[]
数组。
首先,我们利用IntStream
的int
值从标准可打印ASCII集创建一个Character[]
测试数组,通过迭代ASCII范围并将每个值映射到一个字符Stream
中,将它们强制转换为char
基元类型,然后将其转换为Character
对象:
Character[] asciiCharacters = IntStream.range(32, 127)
.mapToObj(i -> Character.valueOf((char)i))
.toArray(Character[]::new);
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
)
);
使用Dollar非常简单:
Integer[] array = ...;
int[] primitiveArray = $(array).toIntArray();
$
!虽然我认为这并不被鼓励…… - Ole V.V.这里是适用于所有基本类型的通用解决方案
/**
* 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 转换为 int
Integer[] a = ...
int[] t = (int[]) asPrimitiveArray(int.class, a);
是的,我们可以将对象数组转换为基本类型,请参考下面的代码。 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();
}
i -> i
(使用拆箱)代替Integer::intValue
。 - robinstInteger:: intValue
,那么为什么要创建一个新的lambda,当该方法已经可用? - AndreasArrays.setAll(unboxed, i -> boxed[i]);
是一个不错的替代方案,可以取代 for 循环。 - Björn ZurmaarsetAll
只有与流相同的原始类型重载,因此您无法将其用于byte
,但是您可以执行Arrays.setAll(array, i -> byteArray[i] = array[i])
,这也会写入原始数组。 - Alex - GlassEditor.com