I'm trying to find an elegant way to convert a Stream<String> to float[].
Until now I've come out with:
Float[] data = input.map(Float::valueOf).toArray(Float[]::new);
But I actually need a float[] and when I try:
float[] data = input.map(x -> Float.parseFloat(x)).toArray(size -> new float[]);
I get an error cannot convert Object[] to float[], which I don't really understand.
There is no way of getting float[] directly from any Stream in Java yet. There are "only" 3 available converting mechanisms to numeric Stream interfaces:
mapToInt(ToIntFunction<? super T> mapper) -> IntStreammapToLong(ToLongFunction<? super T> mapper) -> LongStreammapToDouble(ToDoubleFunction<? super T> mapper) -> DoubleStreamThus the only way is to use double instead, which is fairly easy:
double[] data = input.mapToDouble(Double::parseDouble).toArray();
If you insist to get the float[] from double[], it's another issue where might help the Guava library:
float[] floatArray = Floats.toArray(Doubles.asList(data));
// You can collect Stream to a Collection and pass directly Floats.toArray(list);
Or a simple for-loop:
float[] floatArray = new float[data.length];
for (int i = 0 ; i < data.length; i++) {
floatArray[i] = (float) data[i];
}
Alternatively, you might use the method toArray(IntFunction<A[]> generator) which returns the array of an Object type. However, to unbox Float, you have to use the for-loop again in the very same way - it gives no difference except you can work with Float[] directly, although boxed.
map(Function<? super T,? extends R> mapper) -> Stream<R>Here is the use:
Float[] data = input.map(Float::valueOf).toArray(Float[]::new);
There is a minor error in your code, which we will fix first to reveal the larger problem at hand:
float[] data = input.map(x -> Float.parseFloat(x)).toArray(size -> new float[]);
should be:
float[] data = input.map(x -> Float.parseFloat(x)).toArray(size -> new float[size]);
^this is new
Even if it might not seem like it, your question is realted to generics. Let us take a look at the definition of Stream#toArray(...):
public <A> A[] toArray(IntFunction<A[]> generator)
Since this method is generic in A, the type A must not be a primitive. You, on the other hand, try to set A to float (this is done through type inference, this is why you do not see the generic parameters in your code). The compiler now complains that:
error: incompatible types: inference variable A has incompatible bounds
float[] data = input.stream().map(x -> Float.parseFloat(x)).toArray(size -> new float[size]);
^
equality constraints: float
upper bounds: Object
where A is a type-variable:
A extends Object declared in method <A>toArray(IntFunction<A[]>)
1 error
This question and its answer provide solutions/workarounds to the problem of converting a String-stream to a float[].
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With