We can use Stream
API to create primitive type arrays from their boxed object counterparts.
For Character[]
array conversion to char[]
, using an accordingly size-allocated custom Collector
, with Supplier<CharBuffer>
, BiConsumer<CharBuffer, Character>
accumulator, BinaryOperator<CharBuffer>
combiner and Function<CharBuffer, char[]>
finisher), as following will work:
Collector<Character, CharBuffer, char[]> charArrayCollector = Collector.of(
() -> CharBuffer.allocate(95),
CharBuffer::put,
CharBuffer::put,
CharBuffer::array
);
It supplies the CharBuffer
for the printable ASCII chars, accumulating each streamed Character into a CharBuffer instance, combining parallelized processing results from multiple CharBuffer instances in correct order and finally builds the desired char[]
array from the accumulated and combined results, after all threads have finished.
First, we're creating a Character[]
test array from the standard printable ASCII set, by utilizing the int
values from an IntStream
, by iterating the ASCII range and mapping each value into a Character Stream
, after casting them to char
primitives and converting those to Character
objects:
Character[] asciiCharacters = IntStream.range(32, 127)
.mapToObj(i -> Character.valueOf((char)i))
.toArray(Character[]::new);
Now, we simply need to create a Stream
of Characters from the Character
array, which then can be collected into a char[]
array, by the custom Collector.
char[] asciiChars = Stream.of(asciiCharacters ).collect(charArrayCollector);
This works for other Number
types accordingly:
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
)
);
The primitive types, for which Stream
API supports it, can be converted a bit easier:
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
)
);