这个问题几乎与此one相同,但是方向相反。
我知道Java 8中没有FloatStream
,float []的用例不多,但是我有一个用例:
在JavaFX 3D中处理TriangleMesh
时,您必须为整个网格的顶点的3D坐标提供ObservableFloatArray
。
作为一些计算的结果,我将所有这些坐标存储在List
中,并将所有这些坐标一次性添加到网格中,我将使用以下方法之一调用triangleMesh.getPoints().addAll()
:
可以使用
ObservableFloatArray
,FXCollections.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()));
但这会在添加到可观察数组的每个新顶点上触发关联的监听器,并且对于大量的顶点,这会影响性能。
如果存在
FloatStream
和flatMapToFloat()
,我将执行以下操作: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;
}
}
这支持并行处理,但是,对于仅包含数据复制的操作,并行处理没有任何好处。