如何将二维数组压缩为一维数组?

29

如何将二维数组int originalArray[][]平坦化为一维数组?

    int a [] = {1,2,6,7,2};
    int b [] = {2,44,55,2};
    int c [] = {2,44,511,33};

    int originalArray [][] = new int[][]{a,b,c};
9个回答

46
使用Guava,你可以使用以下两种方式之一: int[] all = Ints.concat(originalArray); 或者 int[] all = Ints.concat(a, b, c);

13
为什么被踩了?谁想在需要这样做的时候写那么多代码呢? - Kevin Bourrillion
有没有一种方法可以对对象数组执行相同的操作? - gvlasov
3
ObjectArrays.concat - Kevin Bourrillion

43

使用Java 8,您可以“flatMap”内部数组:

int[] flatArray = Arrays.stream(originalArray)
        .flatMapToInt(Arrays::stream)
        .toArray();
或者:
int[] flatArray = Stream.of(a, b, c)
        .flatMapToInt(Arrays::stream)
        .toArray();

9

一个简单的for循环就可以实现,这并不难,但会取决于您希望复制数值的顺序。例如(基于您的示例中所有数组长度相同的事实):

int[] newArray = new int[3 * a.length];
int index = 0;
for (int n = 0; n < a.length; n++) {
    newArray[index++] = a[n];
    newArray[index++] = b[n];
    newArray[index++] = c[n];
}

或者(不同的顺序,a、b、c可以长度不同):
int[] newArray = new int[a.length + b.length + c.length];
System.arraycopy(a, 0, newArray, 0, a.length);
System.arraycopy(b, 0, newArray, a.length, b.length);
System.arraycopy(c, 0, newArray, a.length + b.length, c.length);

1
示例数组长度不同。a.length == 5,b.length == 4,c.length == 4。 - phihag
1
也许值得一提的是,如果有必要的话,这两个示例最终展开的数组顺序是不同的。在第一个示例中,数组被“编织”在一起,而在第二个示例中,它们是“端对端”放置的,如果这有意义的话。 - Kevin K
1
@Kevin,我想我提到了:不同的顺序,a、b、c可以有不同的长度 - rsp

4
int[] oneDArray = new int[arr.length*arr.length];
    //Flatten 2D array to 1D array...
    int s = 0;
    for(int i = 0; i < arr.length; i ++) 
          for(int j = 0; j < arr.length; j ++){                           
              oneDArray[s] = arr[i][j];
              s++;
          } 

4

有两个步骤:

1)找出创建新向量(1维数组)所需的元素总数

2)按预定义顺序迭代遍历您的2D数组,并将其元素复制到创建的向量中

int elementsNumber = 0;

for (int i = 0; i < originalArray.length; i++) {
   elementsNumber += originalArray[i].length;
}

int[] newArray = new int[elementsNumber];
int j = 0;
for (int i = 0; i < originalArray.length; i++) {
   System.arrayCopy (originalArray[i], 0, newArray, j, originalArray[i].length);
   j += originalArray[i].length;
}

2

由于数组无法扩展(即在初始化时必须声明大小),因此您必须对数组进行两次遍历:

int size = 0;
for (int[] ar : originalArray) size += ar.length;
int[] result = new int[size];
int pos = 0;
for (int[] ar : originalArray) {
    System.arraycopy(ar, 0, result, pos, ar.length);
    pos += ar.length;
}

哇,我很惊讶递归不是必需的。 - dclowd9901
不使用循环是否可能? - Jessy
@Jessy 嗯,你可以使用递归,但那会让它变得更混乱和更慢。 - phihag
我觉得我应该使用arraycopy :-) - Jessy
请注意:尽管没有明确指定该要求,使用这种技术,没有办法在保留其长度的情况下返回原始数组。@rsp提出的解决方案是一种能够反转该过程的技术,但需要指出的是,展平的要求将决定解决方案。 - nicerobot

0
以下代码可以将不同大小的二维数组(内部数组)合并为一个一维数组:
 public static Integer[] merge2DArrays(int[][] twoDArray){
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < twoDArray.length; i++) {
            for (int j = 0; j < twoDArray[i].length; j++) {
                list.add(twoDArray[i][j]);
            }
        }
    return list.toArray(new Integer[list.size()]);
    }

0

使用IntStream的一行代码

IntStream.concat(
    IntStream.concat( IntStream.of(originalArray[0]), IntStream.of(originalArray[1]) ),
        IntStream.of(originalArray[2]) ).toArray();

获取: [1, 2, 6, 7, 2, 2, 44, 55, 2, 2, 44, 511, 33]


-1

计算originalArray中元素的总数。创建与其长度相同的新数组。逐个将元素复制到新数组中。

我不熟悉任何可用于此操作的库函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接