int [] [] to int [] с использованием метода System.arracopy - PullRequest
0 голосов
/ 25 мая 2018

Если я хочу преобразовать массив int[][] в int[] в java, я использую код, показанный ниже.

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];
     }
}

Я только недавно познакомился с методом System.arraycopy.Это, вероятно, самый эффективный способ скопировать массив в Java.Поэтому я попытался реализовать его аналогичным образом, показанным ниже.

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);
}

Однако полученный массив сильно искажен и никак не представляет исходный массив.

Ответы [ 3 ]

0 голосов
/ 26 мая 2018

Это то, что вы хотите:

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);
0 голосов
/ 26 мая 2018

Детали могут зависеть от того, известен ли массив как прямоугольный или нет.Но независимо от этого, я бы рекомендовал просто включить это в служебный метод, который реализован в общем виде и работает для всех видов входных массивов.

Пример показан ниже.Метод flatten - это то, что вы ищете.

flattenWithStreams - это просто пример, показывающий, что это можно кратко решить с помощью потоков.Я не делал подробного анализа производительности, но подход, использующий 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();
    }
}
0 голосов
/ 25 мая 2018

Параметры

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.

https://www.tutorialspoint.com/java/lang/system_arraycopy.htm

Это необходимо сделать внутри цикла:

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);
...