10

I am trying to convert a double[] to float[] using Java 8 lambda calculus. So far, I just created a toy method which should be revised. Trying to find help for converting primitive arrays. Mostly, is there any approach to get rid of the guava conversion because converting to List and back are too heavy for large arrays.

import com.google.common.primitives.Floats;

public static float[] doubleToFloat(double[] vector) {
    Float[] f = Arrays.stream(vector).<Float>mapToObj(x -> (float) x).toArray(Float[]::new);
    return Floats.toArray(Arrays.asList(f));
}
andih
  • 5,570
  • 3
  • 26
  • 36
MG.
  • 449
  • 6
  • 15
  • 1
    Interestingly enough, there isn't a specialized stream for `Float` - there's only `IntStream`, `DoubleStream`, and `LongStream` predefined. For `float`, it just may be the case that you have to do all of this fiddly work. – Makoto Dec 16 '14 at 04:22
  • 1
    Why does it need to be done using lambda calculus? – Paul Boddington Dec 16 '14 at 04:43
  • @pbabcdefp for experimenting. Trying to find a neat way to get rid of for loop – MG. Dec 16 '14 at 04:56
  • 2
    See http://stackoverflow.com/a/26970398/2711488 – Holger Dec 16 '14 at 09:54

2 Answers2

7

There is no specialized FloatStream, so what you want is not doable with the Streams API.

If you want to get the benefits of float (half the memory of double) and still use streams, you will have to store your floats encoded in ints:

double[] doubles = new double[]{1.2, 3.5, 4};

int[] floatsAsInts = Arrays.stream(doubles)
     .mapToInt(d -> Float.floatToRawIntBits((float) d))
     .toArray();

Arrays.stream(floatsAsInts)
     .forEach(i -> System.out.println(Float.intBitsToFloat(i)));

You would have to have an overwhelmingly good reason to torture yourself like this. Unless you are planning to store a hundred million numbers in this array, you are likely better off just using double[].

Misha
  • 27,433
  • 6
  • 62
  • 78
4

You can still use an IntStream as a looper for your double array.

public static float[] doubleToFloat(double[] vector) {
    float[] f = new float[vector.length];
    IntStream.range(0, f.length).forEach(i -> f[i] = (float) vector[i]);
    return f;
}

Yes this is not a one-liner, and somehow similar to a traditional loop, but the Stream API is not always a substitute. A for loop would largely do the job here.

Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • 2
    It does have the advantage of allowing the float[] array to be filled in parallel, since the order is not important. – Steve K Dec 16 '14 at 23:45