【问题标题】:Java : Resizing a multidimensional arrayJava:调整多维数组的大小
【发布时间】:2011-04-27 02:05:45
【问题描述】:

我有一个从字符串构建的多维数组,最初创建的大小为 [50][50],它太大了,现在数组中充满了空值,我目前正在尝试删除这些空值,我已设法将数组的大小调整为 [requiredSize][50] 但无法进一步缩小它,有人可以帮我解决这个问题吗?我已经在互联网上搜索过这样的答案,但找不到。

这也是我的完整代码(我意识到我的代码中可能有一些非常不干净的部分,我还没有清理任何东西)

import java.io.*;
import java.util.*;

public class FooBar
{
  public static String[][] loadCSV()
  {
    FileInputStream inStream;
    InputStreamReader inFile;
    BufferedReader br;
    String line;
    int lineNum, tokNum, ii, jj;
    String [][] CSV, TempArray, TempArray2;

    lineNum = tokNum = ii = jj  = 0;
    TempArray = new String[50][50];

    try
    {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Please enter the file path of the CSV");
        String fileName = in.readLine();
        inStream = new FileInputStream(fileName);
        inFile = new InputStreamReader(inStream);
        br = new BufferedReader(inFile);
        StringTokenizer tok,tok2;


        lineNum = 0;
            line = br.readLine();
            tokNum = 0;
            tok = new StringTokenizer(line, ",");

            while( tok.hasMoreTokens())
            {
                TempArray[tokNum][0] = tok.nextToken();
                tokNum++;
            }
            tokNum = 0;
            lineNum++;

            while( line != null)
            {
                    line = br.readLine();
                    if (line != null)
                    {
                        tokNum = 0;
                        tok2 = new StringTokenizer(line, ",");

                        while(tok2.hasMoreTokens())
                        {
                            TempArray[tokNum][lineNum] = tok2.nextToken();
                            tokNum++;
                        }
                    }
                    lineNum++;
            }
    }    
    catch(IOException e)
    {
        System.out.println("Error file  may not be accessible, check the path and try again");
    }

    CSV = new String[tokNum][50];
    for (ii=0; ii<tokNum-1 ;ii++)
    {
        System.arraycopy(TempArray[ii],0,CSV[ii],0,TempArray[ii].length);
    }
    return CSV;
}    
public static void main (String args[])
{
    String [][] CSV;
    CSV = loadCSV();
    System.out.println(Arrays.deepToString(CSV));
}
}                

CSV 文件如下所示

Height,Weight,Age,TER,Salary
163.9,46.8,37,72.6,53010.68
191.3,91.4,32,92.2,66068.51
166.5,51.1,27,77.6,42724.34
156.3,55.7,21,81.1,50531.91

显然它可以采用任何大小,但这只是一个示例文件。

我只需要调整数组的大小,使其不包含任何空值。

我也明白在这里列出一个列表会是一个更好的选择,但由于外部限制,这是不可能的。只能是多维数组。

【问题讨论】:

  • 如果不能选择使用列表,您可以拥有自己的动态数组实现,在需要时扩展数组并复制新构造的数组中的旧值。或者您可以读取该文件两次。首先找到行数和列数,然后在第二次读取定义数组时,填写数组中的值

标签: java resize multidimensional-array arrays


【解决方案1】:

这是一个观察和建议。

观察:在 Java 中处理(多维)数组很困难。

建议:Java 中不要使用数组来表示复杂的数据类型。

为您的数据创建类。创建人员列表:

class Person {
    String height;  //should eventually be changed to a double probably
    String weight;  // "
    //...

    public Person( String height, String weight /*, ... */ ) {
       this.height = height;
       this.weight = weight;
       //...
    }
}

List<Person> people = new ArrayList<Person>();
String line;
while ( (line = reader.nextLine()) != null ) {
    String[] records = line.split(",");
    people.add(new Person (records[0], records[1] /*, ... */));
}

【讨论】:

  • 我会这样做但是,我不能保证 CSV 文件每次都会使用相同的标题,这只是一个格式正确的示例 CSV,我永远不知道数据实际上可以保存什么
【解决方案2】:

10 比 1 这是家庭作业。不过,看来你已经考虑过了。

不要使 TempArray 变量。制作一个“字符串列表”。比如:

List<List<String>> rows = new ArrayList<ArrayList<String>>();

while(file.hasMoreRows()) {            //not valid syntax...but you get the jist
  String rowIText = file.nextRow();    //not valid syntax...but you get the jist
  List<String> rowI = new ArrayList<String>(); 

  //parse rowIText to build rowI --> this is your homework

  rows.add(rowI);

}

//now build String[][] using fully constructed rows variable

【讨论】:

    【解决方案3】:

    我认为您需要对程序进行 3 处更改

    • 在您的while 循环之后lineNum 将比文件中的行数多1,因此不要将CSV 声明为String[tokNum][50],而是将其声明为CSV = new String[tokNum][lineNum-1];
    • tokNum 将是一行中的字段数,因此您的 for 循环条件应该是 ii&lt;tokNum 而不是 ii&lt;tokNum-1
    • arraycopy 的最后一个参数应该是lineNum-1

    即构建 CSV 数组的修改代码是:

    CSV = new String[tokNum][lineNum-1];
    for (ii=0; ii<tokNum ;ii++)
    {
        System.arraycopy(TempArray[ii],0,CSV[ii],0,lineNum-1);
    }
    

    然后输出将是:

    [[Height, 163.9, 191.3, 166.5, 156.3], [Weight, 46.8, 91.4, 51.1, 55.7], 
    [Age, 37, 32, 27, 21], [TER, 72.6, 92.2, 77.6, 81.1],
    [Salary, 53010.68, 66068.51, 42724.34, 50531.91]]
    

    请注意,您实际上并不需要将文件的第一行与其他文件分开处理,但这是您可以在清理过程中涵盖的内容。

    【讨论】:

    • 谢谢,这正是我想要做的,我发誓这是我尝试过的,我可能在深夜犯了一个错误,并多次尝试了同样的事情。非常感谢,我会在您的答案上按向上箭头,但我没有所需的声誉
    • @Aaron 很高兴它有帮助。 PS。无论您有多少声誉,您都可以为自己的自己的问题的答案投票。
    猜你喜欢
    • 2018-09-21
    • 2011-02-08
    • 1970-01-01
    • 2020-11-15
    • 2015-02-27
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    相关资源
    最近更新 更多