假设我有一个2d数组,如下所示:
[[O, X, null, O, O, null, null], [null, null, O, null, null, O, O]]
我希望它看起来像这样:
[[O, X, O, O, null, null, null], [O, O, O, null, null, null, null]]
我试过了,但不起作用:
String[][] a = new String[row][col];
String[][] b = new String[row][col];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
if (a[i][j] != null) {
a[i][j] = b[i][j];
} else {
b[i][j] = a[i][j + 1];
}
}
}
解决问题的一些要点
- 您需要使用
a[i].length
进行内部循环 - 这里的
a[i][j] = b[i][j];
需要在b
中分配a
值 - 您需要为
b
2D数组的每一行使用计数器索引,并且无论何时发现不为null,都会在存储后递增该索引,剩余的索引将被取消为null
for (int i = 0; i < a.length; i++) {
int indNew = 0; // Index for every row
for (int j = 0; j < a[i].length; j++) {
if (a[i][j] != null) {
b[i][indNew] = a[i][j]; // store not null value
indNew++; // increase after storing
}
}
}
首先让我印象深刻的是,您从不检查内部数组的长度。给定该示例,它将只检查前两个元素。
// Before
for (int j = 0; j < status.length; j++)
// Solution
for (int j = 0; j < status[i].length; j++)
至于具体的问题,你可以通过跟踪第一个null的索引并将你遇到的任何元素移动到它来完成
int lastEmpty = 0;
for (int j = 0; j < status[i].length; j++) {
// Move to the best compressed position
if (status[i][j] != null && status[i][lastEmpty] == null) {
status[i][lastEmpty] = status[i][j];
status[i][j] = null;
}
// Shift to always be the first null
if (status[i][lastEmpty] != null) {
lastEmpty++;
}
}
您可以在该数组上迭代,对于每一行filter
,从null元素中取出,并收集剩余的相同长度的toArray
,其中null最后一个:
String[][] arr1 = {
{"O", "X", null, "O", "O", null, null},
{null, null, "O", null, null, "O", "O"}};
String[][] arr2 = Arrays.stream(arr1)
.map(row -> Arrays.stream(row)
// filter out null elements
.filter(Objects::nonNull)
// new array of the same length, nulls last
.toArray(q -> new String[row.length]))
.toArray(String[][]::new);
// output
Arrays.stream(arr2).map(Arrays::toString).forEach(System.out::println);
[O, X, O, O, null, null, null]
[O, O, O, null, null, null, null]
另请参阅:从旧的2d数组中删除null,并将非null元素放入新的2d数组
您不需要创建新的2D数组来存储其更新版本,null
值可以简单地移动到每行的末尾,然后使用Arrays.fill
从计算的索引开始设置null。
更新:该方法可以是通用的
public static <T> void moveNulls(T[][] status) {
for (T[] row : status) {
if (null == row) {
continue;
}
int id = 0;
for (int i = 0; i < row.length; i++) {
if (row[i] != null) {
row[id++] = row[i];
}
}
Arrays.fill(row, id, row.length, null);
}
}
测试
String[][] status = {
{"aaa", null, "bbb", null, null, "ccc"},
{null, "bbb", null, null, "ccc", "ddd", null, "eee"},
{null, null, "fff", null, "ccc", "ddd", null, "ggg", null},
};
moveNulls(status);
for (String[] row : status) {
System.out.println(Arrays.toString(row));
}
输出
[aaa, bbb, ccc, null, null, null]
[bbb, ccc, ddd, eee, null, null, null, null]
[fff, ccc, ddd, ggg, null, null, null, null, null]