gpt4 book ai didi

java-8 - 如何从流中获取可观察的 float 组?

转载 作者:行者123 更新时间:2023-12-04 17:18:46 25 4
gpt4 key购买 nike

这个问题几乎与此one相同,但是方向相反。

我知道Java 8中没有FloatStream,float []的用例不多,但是我有一个用例:

在JavaFX 3D中处理TriangleMesh时,您必须为整个网格的顶点的3D坐标提供ObservableFloatArray

作为一些计算的结果,我将所有这些坐标存储在List中,并将所有这些坐标一次性添加到网格中,我将使用以下方法之一调用triangleMesh.getPoints().addAll():

  • addAll(ObservableFloatArray src)
  • addAll(float ... elements)
  • addAll(ObservableFloatArray src,int srcIndex,int length)
  • addAll(float [] src,int srcIndex,int length)

  • 可以使用 ObservableFloatArrayFXCollections.observableFloatArray()FXCollections.observableFloatArray(ObservableFloatArray array)创建 FXCollections.observableFloatArray(float... values)

    假设每个顶点都有这个pojo:
    private class Vertex {
    private final float x;
    private final float y;
    private final float z;

    public Vertex(float x, float y, float z){
    this.x=x; this.y=y; this.z=z;
    }

    public float[] getCoordenates(){
    return new float[]{x,y,z};
    }
    }

    执行一些计算后,我有了 List<Vertex> listVertices。我需要生成 float[] arrayVertices才能最终调用 triangleMesh.getPoints().addAll(arrayVertices);

    现在,这就是我正在做的事情:
    listVertices.forEach(vertex->triangleMesh.getPoints().addAll(vertex.getCoordenates()));

    但这会在添加到可观察数组的每个新顶点上触发关联的监听器,并且对于大量的顶点,这会影响性能。

    如果存在 FloatStreamflatMapToFloat(),我将执行以下操作:
    float[] arrayVertices = listVertices.stream()
    .map(vertex->FloatStream.of(vertex.getCoordenates()))
    .flatMapToFloat(f->f).toArray();
    triangleMesh.getPoints().addAll(arrayVertices);

    就像我实际上使用int []的人脸索引列表一样:
    int[] arrayFaces = listFaces.stream()
    .map(face->IntStream.of(face.getFaceIndices()))
    .flatMapToInt(i->i).toArray();
    triangleMesh.getFaces().addAll(arrayFaces);

    但据我所知,无法使用流。

    预先感谢任何涉及流的可能解决方案。

    最佳答案

    请记住,Stream定义了一个操作而不是一个存储。因此,对于大多数操作,当使用CPU寄存器时,使用float仅比double值提供的好处很小。从理论上讲,可以使用SSE或GPU加速操作的改进,但这与本文无关。

    因此,您可以使用DoubleStream进行该操作,唯一需要的是一个能够将DoubleStream收集到float[]数组中的收集器:

    float[] arrayVertices = listVertices.stream()
    .flatMapToDouble(vertex->DoubleStream.of(vertex.x, vertex.y, vertex.z))
    .collect(FaCollector::new, FaCollector::add, FaCollector::join)
    .toArray();

    static class FaCollector {
    float[] curr=new float[64];
    int size;
    void add(double d) {
    if(curr.length==size) curr=Arrays.copyOf(curr, size*2);
    curr[size++]=(float)d;
    }
    void join(FaCollector other) {
    if(size+other.size > curr.length)
    curr=Arrays.copyOf(curr, size+other.size);
    System.arraycopy(other.curr, 0, curr, size, other.size);
    size+=other.size;
    }
    float[] toArray() {
    if(size!=curr.length) curr=Arrays.copyOf(curr, size);
    return curr;
    }
    }

    这支持并行处理,但是,对于仅包含数据复制的操作,并行处理没有任何好处。

    关于java-8 - 如何从流中获取可观察的 float 组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26951431/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com