如何使用Java 8流将float的ArrayList转换为原始float数组?

How can I convert an ArrayList of floats to a primitive float array using java 8 streams?

我正在尝试使用Java 8 Stream API将包含float值的ArrayList转换为原始浮点数组。
到目前为止我尝试的是这样的:

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


老实说:用流来做这个没有好的内置方法。对不起,但这是事实。

如果你可以使用double[],你可以使用floatList.stream().mapToDouble(f -> f.doubleValue()).toArray(),但这可能不是你所希望的。

如果要对流执行此操作,则需要编写自己的自定义大小调整列表类型并收集到该类型,但除此之外没有任何作用。你必须写一些像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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));
}

将您的集合直接转换为没有流的float[]会更简单,或者通过简单的循环将其自身转换为 -

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

或者与第三方库,例如番石榴Floats.toArray


如果将Eclipse Collections Collectors2Stream collect方法一起使用,则可以完成此操作。

1
2
3
4
5
6
7
8
9
10
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();

您也可以使用LazyIterate类在不使用Streams的情况下完成此操作。

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

如果使用内置的原始集合,则可以将FloatList简单地转换为float数组,如下所示:

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

注意:我是Eclipse Collections的提交者。


这个怎么样?您可以使用FloatBuffer来收集float[],例如:

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

Object[]转换为基本数组(在您的情况下为float [])是不可能的。

可能的替代方式(假设Nonnull值)可以是:

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

来自apache的Commons通过ArrayUtils.toPrimitive()提供了一个util