4

I'm trying to convert an ArrayList containing float values to an array of primitive floats using the Java 8 Stream API. What I tried so far looked something like this:

List<Float> floatList = new ArrayList<Float>(); 
float[] floatArray = floatList.stream().map(i -> i).toArray(float[]::new)
5

4 Answers 4

9

Honestly: there's no good built-in way to do this with streams. Sorry, but it's the truth.

If you can live with a double[], you can use floatList.stream().mapToDouble(f -> f.doubleValue()).toArray(), but that's probably not what you're hoping for.

If you want to do it with streams, you'll need to write your own custom resizing list type and collect to it, but nothing short of that is going to work. You'd have to write something like

float[] toFloatArray(Collection<Float> collection) {
  class FloatArray {
    int size;
    float[] array;
    FloatArray() {
      this.size = 0;
      this.array = new float[10];
    }
    void add(float f) {
      if (size == array.length) {
        array = Arrays.copyOf(array, array.length * 2);
      }
      array[size++] = f;
    }
    FloatArray combine(FloatArray other) {
      float[] resultArray = new float[array.length + other.array.length];
      System.arraycopy(this.array, 0, resultArray, 0, size);
      System.arraycopy(other.array, 0, resultArray, size, other.size);
      this.array = resultArray;
      this.size += other.size;
      return this;
    }
    float[] result() {
      return Arrays.copyOf(array, size);
    }
  }
  return collection.stream().collect(
     Collector.of(
         FloatArray::new, FloatArray::add, 
         FloatArray::combine, FloatArray::result));
}

It'd be much simpler to convert your collection directly to a float[] without streams, either by yourself with a straightforward loop --

float[] result = new float[collection.size()];
int i = 0;
for (Float f : collection) {
  result[i++] = f;
}

or with a third-party library, e.g. Guava's Floats.toArray.

Sign up to request clarification or add additional context in comments.

Comments

4

How about this? You can use FloatBuffer to collect the float[], for example:

float[] result = floatList.stream().collect(
  ()-> FloatBuffer.allocate(floatList.size()), 
  FloatBuffer::put,
  (left, right) -> { 
     throw new UnsupportedOperationException("only be called in parallel stream");
  }
).array();

Comments

3

If you use Eclipse Collections Collectors2 with the Stream collect method, you can accomplish this.

ArrayList<Float> floats = new ArrayList<>();
floats.add(new Float(1.0f));
floats.add(new Float(2.0f));
floats.add(new Float(3.0f));
float[] floatArray =
        floats.stream()
                .collect(Collectors2.collectFloat(
                                Float::floatValue,
                                FloatLists.mutable::empty))
                .toArray();

You can also accomplish this without using Streams by using the LazyIterate class.

float[] array =
    LazyIterate.adapt(floats).collectFloat(Float::floatValue).toArray();

If you use the built in primitive collections, you can simply convert a FloatList to a float array as follows:

float[] array = FloatLists.mutable.with(1.0f, 2.0f, 3.0f).toArray();

Note: I am a committer for Eclipse Collections.

Comments

1

It's not possible to convert an Object[] to a primitive array(float [] in your case).

Alternate way possible(assuming Nonnull values) could be as:

Object[] arr = floatList.toArray();
for (Object o : arr) {
    System.out.println((float)o);
}

Commons from apache provides a util for it though ArrayUtils.toPrimitive()

2 Comments

You can't cast an Object[] to a Float[] it will throw a ClassCastException
I mean, it is possible with streams, just only for int[], long[], and double[]. And you'd have to write floatList.toArray(new Float[0]), you can't do that cast.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.