【问题标题】:Convert Java stream of strings to array of float将Java字符串流转换为浮点数组
【发布时间】:2018-06-22 16:42:34
【问题描述】:

我正在尝试找到一种优雅的方法将 Java Stream<String> 转换为浮点数组。到现在为止我已经出来了:

Float[] data = input.map(Float::valueOf).toArray(Float[]::new);

但我实际上需要float[],当我尝试时:

float[] data = input.map(x -> Float.parseFloat(x)).toArray(size -> new float[]);

我得到一个错误,无法将Object[] 转换为float[],我不太明白。

我做错了什么?

【问题讨论】:

  • input流的元素类型是什么?
  • 没有FloatStream,所以我认为如果不编写从Floatdouble 转换的自定义收集器,这是不可能的。
  • double[] 会这样做吗?如果是这样,您可以使用Stream#mapToDouble(...) 获取DoubleStream
  • 为什么是float 而不是double?然后你可以使用DoubleStream
  • 副本完全不是 OP 想要的。如果有的话,this 是 OP 想要的。但即使这样也不能回答为什么它不起作用的问题。投票重新开放。

标签: java arrays java-stream


【解决方案1】:

没有办法直接从 Java 中的任何 Stream 获取 float[]。数字 Stream 接口“只有”3 种可用的转换机制:

因此,唯一的方法是改用double,这相当简单:

double[] data = input.mapToDouble(Double::parseDouble).toArray();

如果您坚持从double[] 获取float[],这是另一个可能有助于Guava 库的问题:

float[] floatArray = Floats.toArray(Doubles.asList(data));
// You can collect Stream to a Collection and pass directly Floats.toArray(list);

或者简单的for-loop

float[] floatArray = new float[data.length];
for (int i = 0 ; i < data.length; i++) {
    floatArray[i] = (float) data[i];
}

或者,您可以使用方法toArray(IntFunction&lt;A[]&gt; generator),它返回一个对象类型的数组。但是,要拆箱 Float,您必须以相同的方式再次使用 for 循环 - 除了您可以直接使用 Float[] 之外,它没有任何区别,尽管已装箱。

这里是用法:

Float[] data = input.map(Float::valueOf).toArray(Float[]::new);

【讨论】:

    【解决方案2】:

    您的代码中有一个小错误,我们将首先修复它以揭示手头的更大问题:

    float[] data = input.map(x -> Float.parseFloat(x)).toArray(size -> new float[]);
    

    应该是:

    float[] data = input.map(x -> Float.parseFloat(x)).toArray(size -> new float[size]);
                                                                                 ^this is new
    

    即使看起来不像,您的问题也与泛型有关。让我们看看definition of Stream#toArray(...)

    public <A> A[] toArray​(IntFunction<A[]> generator)
    

    由于此方法在A 中是通用的,因此A 类型不能是原始类型。另一方面,您尝试将A 设置为float(这是通过type inference 完成的,这就是您在代码中看不到通用参数的原因)。编译器现在抱怨:

    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 为将String-stream 转换为float[] 的问题提供解决方案/变通方法。

    【讨论】:

    • 缺少的大小实际上是一个错字,在我得到的代码中。我不会解决这个问题,否则你的答案将失去意义。谢谢
    【解决方案3】:

    我的图书馆有更好的方法AbacusUtil

    float[] result = Stream.of(input).mapToFloat(Float::parseFloat).toArray();
    

    【讨论】:

    • 感谢您完成了核心 Java 库团队无法完成的工作。单精度在任何涉及硬件加速的地方都很方便。
    【解决方案4】:

    您可以通过 floatValue() 方法使用来自 Float 对象的值来创建一个数组:

    Float[] data = input.map(Float::valueOf).toArray(Float[]::new);
    float[] primData = new float[data.length];
    
    for(int x = 0; x < data.length; x ++) {
        primData[x] = data[x].floatValue();
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      • 1970-01-01
      相关资源
      最近更新 更多