繁体   English   中英

从“所有元素为空”的字符串数组中删除空元素

[英]Remove null elements from String array where “All elements are null”

我的任务是解决此代码返回字符串值的问题,但是由于迭代添加了null元素,因此需要修剪或删除这些元素。 在调试期间,数组的值主要包含“所有元素均为null”,但其他解决方案如data.removeAll(Collections.singleton(null)); 不起作用,因为它是元素为null,并且仍然返回原始大小。 有没有办法在初始循环迭代后删除这些元素,还是应该在为数据分配“值”的循环内完成?

码:

    private String[][] getStringsFromSpreadSheet(Sheet ws) {
    int rowNum = ws.getLastRowNum() + 1;
    int colNum = ws.getRow(0).getLastCellNum();
    String[][] data = new String[(rowNum - 1)][colNum];

    int k = 0;
    for (int i = 1; i < rowNum; i++) {
        ws.getRow(i);
        if (ws.getRow(i) != null) {
            for (int j = 0; j < colNum; j++) {
                if (ws.getRow(i).getCell(j) != null) {
                    String value = ws.getRow(i).getCell(j).toString();
                    if (!value.toString().isEmpty()) {
                        data[k][j] = value;
                    }
                }
            }
        }
        k++;
    }
    return data;
}

您可以轻松地从List修剪空值,但是您一直试图将数组错误地转换为List

由于具有二维数组,因此需要创建一个嵌套列表( List<List<String>> )来存储数据。

例如,让我们从一个空的String[][]

    String[][] data = new String[3][3];
    data[0][0] = "foo";
    data[1][1] = "bar";

    //data is a 3x3 array
    for (int i=0; i<data.length; i++) {
        System.out.println(Arrays.toString(data[i]));
    }
    //[foo, null, null]
    //[null, bar, null]
    //[null, null, null]

我们可以获取每个子数组,将其转换为列表,对其进行修剪,然后将非空列表添加到封闭列表中,如下所示:

    List<List<String>> dataList = new ArrayList<>();
    for (int i=0; i<data.length; i++) {
        List<String> temp = new ArrayList<>();
        Collections.addAll(temp, data[i]);
        temp.removeAll(Collections.singleton(null));
        if (!temp.isEmpty()) {
            dataList.add(temp);
        }
    }

然后,我们可以将列表转换回String[][] ,它将被“修剪”为null数据,如下所示:

    String[][] newData = new String[dataList.size()][];
    for (int i=0; i<dataList.size(); i++) {
        List<String> subList = dataList.get(i);
        newData[i] = subList.toArray(new String[subList.size()]);
    }

    //newData is a 2x1 array
    for (int i=0; i<newData.length; i++) {
        System.out.println(Arrays.toString(newData[i]));
    }
    //[foo]
    //[bar]

您只需将其设置为空白字符串即可。 检查else子句。

private String[][] getStringsFromSpreadSheet(Sheet ws) {
int rowNum = ws.getLastRowNum() + 1;
int colNum = ws.getRow(0).getLastCellNum();
String[][] data = new String[(rowNum - 1)][colNum];

int k = 0;
for (int i = 1; i < rowNum; i++) {
    ws.getRow(i);
    if (ws.getRow(i) != null) {
        for (int j = 0; j < colNum; j++) {
            if (ws.getRow(i).getCell(j) != null) {
                String value = ws.getRow(i).getCell(j).toString();
                if (!value.toString().isEmpty()) {
                    data[k][j] = value;
                }
            } else {
                data[k][j] = "";
            }
        }
    }
    k++;
}
return data;

现在,数据将没有任何空值,但可能具有空白/空字符串。

根据您的评论,您似乎必须为getStringsFromSpreadSheet返回String[][] 这个对吗? 如果是这样,就没有一种很好的方法来跟踪多少个单元格为空/不为空。 2D阵列必须为矩形。 因此,如果您的一行中有3列已填充,而一行中只有1列已填充,则数组的宽度必须至少为3列。 我试图在下面直观地表示这一点。

Row | Column 1  | Column 2  | Column 3  |
 1  | something | something | something |
 2  | something |    null   |    null   |

因此,对于以上数据,您必须声明至少2x3的2D数组以适合所有数据。 无论如何,如果您的某一行未填充全部3列,则该行始终会有一个空单元格。 Array.length将始终返回数组的大小,从不返回null / not null的数量。

如果您只能返回String[][]那么您的选择将受到限制。 如果您能够返回其他商品,我们可以为您提供一些解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM