Java 使用System.arracopy方法将int[]]转换为int[]

Java 使用System.arracopy方法将int[]]转换为int[],java,arrays,Java,Arrays,如果我想在java中将int[]]数组转换为int[],我将使用下面显示的代码 final int width = 3, height = 4; final int[][] source = new int[width][height]; final int[] destination = new int[width * height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++)

如果我想在java中将int[]]数组转换为int[],我将使用下面显示的代码

final int width = 3, height = 4;
final int[][] source = new int[width][height];
final int[] destination = new int[width * height];
for (int x = 0; x < width; x++)
{
     for (int y = 0; y < height; y++)
     {
          destination[x * width + y] = source[x][y];
     }
}
final int width = 3, height = 4;
final int[][] source = new int[width][height];
final int[] destination = new int[width * height];
for (int index = 0; index < source.length; index++)
{
    System.arraycopy(source[index], 0, destination, source[index].length, source[index].length);
}
但是,生成的数组严重失真,不能以任何方式表示原始数组

参数

src − This is the source array.

srcPos − This is the starting position in the source array.

dest − This is the destination array.

destPos − This is the starting position in the destination data.

length − This is the number of array elements to be copied.
您需要在循环中执行此操作:

final int width = 3, height = 4;
final int[][] source = new int[width][height];
final int[] destination = new int[width * height];
for (int i = 0; i < source.length; i++)
    System.arraycopy(source[i], 0, destination, i * width, source[i].length);
这就是你想要的:

final int width = 3, height = 4;
final int[][] source = new int[width][height];
final int[] destination = new int[width * height];
for (int i = 0; i < source.length; i++)
     System.arraycopy(source[i], 0, destination, i * width, height);
如果希望它在一般情况下工作(源中的每个子数组大小不同),则需要:

int totalLength = 0;
for (int i = 0; i < source.length; i++)
   totalLength += source[i].length;
final int[] destination = new int[totalLength];
for (int len, i = 0, index = 0; i < source.length; i++, index += len)
        System.arraycopy(source[i], 0, destination, index, len = source[i].length);

这里的细节可能取决于是否知道数组是矩形的。但不管怎样,我建议将其简单地拉入一个通用实现的实用方法中,该方法适用于所有类型的输入数组

下面是一个例子。展平法就是你要找的

FlattWithStreams只是一个例子,表明这可以用streams简洁地解决。我没有做详细的性能分析,但使用arraycopy的方法似乎更快

import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class FlattenArrays
{
    public static void main(String[] args)
    {
        test();
    }

    private static void test()
    {
        int[][] source = new int[3][];
        source[0] = new int[] { 0, 1, 2 };
        source[1] = new int[] { 3, 4, 5, 6 };
        source[2] = new int[] { 7, 8, 9 };

        int destinationA[] = flatten(source);
        System.out.println(Arrays.toString(destinationA));

        int destinationB[] = flattenWithStream(source);
        System.out.println(Arrays.toString(destinationB));
    }

    private static int[] flatten(int array[][])
    {
        int length = 0;
        for (int a[] : array)
        {
            length += a.length;
        }
        int destination[] = new int[length];
        int offset = 0;
        for (int a[] : array)
        {
            System.arraycopy(a, 0, destination, offset, a.length);
            offset += a.length;
        }
        return destination;
    }

    private static int[] flattenWithStream(int array[][])
    {
        return Stream.of(array).flatMapToInt(a -> IntStream.of(a)).toArray();
    }
}

非常感谢您的快速回复。真的没有别的办法吗?我相信没有for循环是可能的,但我的记忆可能只是在捉弄我。@NiklasSimandi使用arraycopy无法将数组数组复制到数组中。但是,您可以将我上面给出的解决方案放入一个方法中并使用它。你可能见过这样的方法被使用。我相信没有for循环是可能的,但我的记忆可能只是在捉弄我。-是的。为什么我在运行同一代码时总是得到ArrayIndexOutOfBoundsException?@NiklasSimandi,因为我为destPost传递了错误的值。我已经编辑了我的答案。当IDE警告您如何使用某个方法时。。。简单的方法是使用该方法的javadoc并仔细阅读。换句话说:您的目标应该是始终准确地理解您正在编写的代码在做什么。Lajos给了你一个很好的回答但最后。。。他只是引用javadoc,不是吗-由于您必须循环调用System.arraycopy,因此您可能希望通过使用此实现确保实际获得性能。我可以看到,对于高度非常小的数组,由于调用该方法的开销,它可能会变慢,这取决于编译器如何处理它等等。