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)
-> IntStream
mapToLong(ToLongFunction<? super T> mapper)
-> LongStream
mapToDouble(ToDoubleFunction<? super T> mapper)
-> DoubleStream
Thus 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