Java

时间:2016-03-14 19:26:06

标签: java arrays collections buffer

我正在寻找一种通过展平将List<List<float[]>>转换为float[]的优雅方式。我觉得这将是一件轻而易举的事,但显然我错了。我不能使用Java 8或外部库来解决问题。我也不知道内部列表和数组的大小,它们不一定具有相同的大小。

这就是我所拥有的,我认为这对于这么简单的任务来说太复杂了:

private float[] toFloatBuffer(List<List<float[]>> buffers) {
    //First: creating a new list to store the Float values
    List<Float> mergedList = new ArrayList<>();
    //Adding the float values to the mergedList
    for(List<float[]> secondBuffer : buffers) {
        for(float[] b : secondBuffer) {
            for(float f : b) {
                mergedList.add(f);
            }
        }
    }
    //Creating the final buffer with the size of mergedList
    float[] merged = new float[mergedList.size()];
    //This doesn't work for some odd reason...
    //float[] merged = mergedList.toArray(); 
    int i = 0;
    //Adding the values of mergedList to merged
    for(float f : mergedList) {
        merged[i++] = f;
    }
    return merged;
}

编辑:由于某些原因,我忘了说外部列表是一个LinkedList。也许这一点很重要。

2 个答案:

答案 0 :(得分:3)

我就是这样做的,虽然我不确定它是否更漂亮,它应该是更高效的esp,因为它不会创建任何Float个对象。

public static float[] flatten(List<List<float[]>> lists) {
    // get the total size.
    int size = 0;
    for (List<float[]> list : lists) 
        for (float[] floats : list) 
            size += floats.length;
    // create an array of the right size.
    float[] ret = new float[size];
    int i = 0;
    for (List<float[]> list : lists)
        for (float[] floats : list) {
            // bulk copy the array
            System.arraycopy(floats, 0, ret, i, floats.length);
            i += floats.length;
        }
    return ret;
}

这会创建一些迭代器,但是Escape Analysis可能会将它们放在堆栈上以避免垃圾。

以下仅创建一个对象

public static float[] flatten(List<List<float[]>> lists) {
    int size = 0;
    for (int i = 0; i < lists.size(); i++) {
        List<float[]> list = lists.get(i);
        for (int j = 0; j < list.size(); j++) {
            float[] floats = list.get(j);
            size += floats.length;
        }
    }
    float[] ret = new float[size];
    int pos = 0;
    for (int i = 0; i < lists.size(); i++) {
        List<float[]> list = lists.get(i);
        for (int j = 0; j < list.size(); j++) {
            float[] floats = list.get(j);
            System.arraycopy(floats, 0, ret, pos, floats.length);
            pos += floats.length;
        }
    }
    return ret;
}

如果您创建List<Float>,则每个元素至少创建一个对象。

答案 1 :(得分:0)

请参阅这个优雅的递归示例,您可以根据自己的需要进行调整:

https://gist.github.com/l-ray/11472207

与任何递归算法一样,如果列表很大,您应该添加一些检查以避免溢出。