如何读取.txt文件并将其结构切换到2D列表

时间:2019-02-17 23:53:36

标签: java list arraylist

我对这些数据结构感到困惑,我只想构建一种2D类型的结构以使用数据。

这是txt文件:

COSTS A B C D E F G H I J SUPPLY Source1 6 7 10 16 5 8 15 15 6 8 175 Source2 10 14 8 17 13 9 18 20 9 7 200 Source3 9 4 8 12 10 10 8 5 9 10 225 Source4 12 8 9 10 6 15 4 9 7 0 300 Source5 6 9 17 7 6 13 6 7 6 0 250 Source6 9 10 9 13 9 8 9 3 4 9 100 Source7 16 18 7 14 5 6 10 5 4 5 150 Source8 7 5 8 3 8 5 10 8 8 14 300 Source9 8 10 9 6 4 9 17 7 5 8 100 Source10 5 8 4 5 7 14 6 3 13 9 200 DEMAND 150 250 110 275 175 350 300 180 90 120

这是我现在的代码:

public static void main(String[] args) {
    Object[][] table = new Object[13][];
    Scanner sc = new Scanner(System.in);
    //sc.useDelimiter("\\Z"); 

    while(sc.hasNextLine()) {
        String sc1 = sc.nextLine();
        ArrayList<String> arrayList = 
            new ArrayList<String>(Arrays.asList(sc1.split(" ")));

        System.out.println(arrayList);      
    }

    sc.close();
}

2 个答案:

答案 0 :(得分:0)

I am guessing you want to load the data into table = new Object[13][]; if so this is the code you need to use;

public static void main(String[] args) {
    Object[][] table = new Object[13][];
    Scanner sc = new Scanner(System.in);
    int i = 0;
    while (sc.hasNextLine()) {
        String sc1 = sc.nextLine();
        table[i] = sc1.split(" ");
        i++;
    }
    sc.close();
    System.out.println(Arrays.deepToString(table));
}

Basically I am just setting each index of the table to a String array that contains strings split by space.

答案 1 :(得分:0)

显然可以使用数组来完成这种事情,但是除非知道要读取的特定数据文件,否则无法轻松知道要读取的文件中包含多少数据行。始终包含相同数量的数据线。许多程序员将使用ArrayList或List接口对象来保存数据,如果仍然需要类型数组,则将集合转换为该类型数组。

  

填充2D阵列:

首先,您需要知道数据文件中实际包含多少个有效文件数据行。最简单的方法是进行两次通过读取。第一遍计算文件中有多少有效数据行,以便可以适当地确定数组大小,然后第二遍填充2D数组。确定文件可能包含的行数的方法很简单,但是没有确定文件是否为有效数据行(实际上包含数据的行)的简便方法。

您的特定数据文件似乎包含三个特定部分:

  1. 标题 部分(文件的第一行);
  2. 原始数据 部分(文件正文);
  3. 需求 部分(文件的最后一行)。

将每个部分检索到单独的数组中可能是有益的,因此我在下面提供的代码演示了如何实现此目的。首先,您需要建立3个类成员变量,它们将在整个类中具有全局作用域:

String[] headerData;  // First data Line in file is the Header Information
Object[][] data;      // The 2D Object Array to hold raw File Data
int[] demandData;     // Last data line in file is the Demand Information

现在将以下方法复制/粘贴到您的班级中:

private void readDataFile(String filePath) {
    Scanner sc;
    int maxColumns = 0;
    int validLines = 0;
    int endLine;
    try {
        sc = new Scanner(new File(filePath));
        String dataLine = "";
        // First Pass: 
        while (sc.hasNextLine()) {
            String fileLine = sc.nextLine().trim();
            /* Skip Blank Lines or lines that start with 
               a comment character (if any)... */
            if (fileLine.equals("") || fileLine.startsWith(";") || fileLine.startsWith("#")) {
                continue;
            }
            validLines++;  //This line must be a valid data line, so increment counter.
            dataLine = fileLine;
            if (validLines == 1) {
                // Get Header Information.
                headerData = dataLine.split("\\s+");  // Grab the Columns Header Names
                maxColumns = headerData.length;       // Get the number of data columns
            }
        }
        endLine = validLines;
        demandData = new int[endLine - 2];          // Initialize the demandData array
        data = new Object[endLine - 2][maxColumns]; // Initialize the data array 
        // Make sure the last line actually contains data
        if (dataLine.equals("")) {
            // No it doesn't so there is no DEMAND line.
            System.out.println("No DEMAND Data Available In File!");
            sc.close();
            return;
        }

        /* Fill the demandData int array with Integer data...
           The dataLine variable at this point will hold 
           the last valid file data line which happend to 
           be the Demand Line   */
        String[] dl = dataLine.split("\\s+"); // split the data line on 1 or more whitespaces.
        // Don't want the word "DEMAND" so we start from 1.
        for (int i = 1; i < dl.length; i++) {
            demandData[i-1] = Integer.parseInt(dl[i]);
        }

        // Second Pass (fill the data aray):
        sc = new Scanner(new File("MyDataFile.txt"));
        validLines = 0;
        while (sc.hasNextLine()) {
            String fileLine = sc.nextLine().trim();
            /* Skip Blank Lines or lines that start with 
               a comment character (if any)... */
            if (fileLine.equals("") || fileLine.startsWith(";") || fileLine.startsWith("#")) {
                continue;
            }
            validLines++;  //This line must be a valid data line, so increment counter.
            if (validLines == endLine) {
                break;
            }
            if (validLines == 1) { continue; }  // Skip the header line
            dl = fileLine.split("\\s+");        // split the data line on 1 or more whitespaces.
            for (int i = 0; i < dl.length; i++) {
                if (i == 0) {
                    data[validLines-2][i] = dl[i]; //String Object - Sources Name
                }
                else {
                    data[validLines-2][i] = Integer.parseInt(dl[i]); // Integer Object
                }
            }
        }
        sc.close();  /* Close the reader.
        Make sure the number of data rows equals the number 
        of Demand values otherwise inform of mismatch. */
        if (data.length != demandData.length) {
            System.out.println("Warning: There is missing DEMAND information (data mismatch)!\n"
                             + "There is no available Demand data for one of the Sources.");
        }
    }
    catch (FileNotFoundException ex) {
        System.err.println(ex.getMessage());
    }
}

这是您可能使用此方法的方式:

readDataFile("10by10.txt");

if (data != null) {
    // Header Information:
    System.out.println("Header Column Names:\n" + 
                 Arrays.toString(headerData) + "\n");

    // The Actual Data:
    System.out.println("File Data:");
    for (int i = 0; i < data.length; i++) {
        System.out.println(Arrays.toString(data[i]));
    }

    // The Demand Information:
    System.out.println("\nDemand Values For Each Row:\n" + 
                 Arrays.toString(demandData) + "\n");
}

如果您提供示例文件数据,则将在控制台窗口中显示以下内容:

Header Column Names:
[COSTS, A, B, C, D, E, F, G, H, I, J, SUPPLY]

File Data:
[Source1, 6, 7, 10, 16, 5, 8, 15, 15, 6, 8, 175]
[Source2, 10, 14, 8, 17, 13, 9, 18, 20, 9, 7, 200]
[Source3, 9, 4, 8, 12, 10, 10, 8, 5, 9, 10, 225]
[Source4, 12, 8, 9, 10, 6, 15, 4, 9, 7, 0, 300]
[Source5, 6, 9, 17, 7, 6, 13, 6, 7, 6, 0, 250]
[Source6, 9, 10, 9, 13, 9, 8, 9, 3, 4, 9, 100]
[Source7, 16, 18, 7, 14, 5, 6, 10, 5, 4, 5, 150]
[Source8, 7, 5, 8, 3, 8, 5, 10, 8, 8, 14, 300]
[Source9, 8, 10, 9, 6, 4, 9, 17, 7, 5, 8, 100]
[Source10, 5, 8, 4, 5, 7, 14, 6, 3, 13, 9, 200]

Demand Values For Each Data Row:
[150, 250, 110, 275, 175, 350, 300, 180, 90, 120]
  

填充2D列表界面:

在这里,我们的操作有所不同,您会发现它可以轻松得多。这次,我们的 readDataFile()方法返回了String类型的2D List Interface对象,我们可以轻松地操作该对象以获取Header Coloumn Names,Raw Data和Demand Data值。

这是方法:

 private List<List<String>> readDataFile(String filePath) {
    Scanner sc;
    List<List<String>> list = new ArrayList<>();
    try {
        sc = new Scanner(new File(filePath));
        while (sc.hasNextLine()) {
            String fileLine = sc.nextLine().trim();
            /* Skip Blank Lines or lines that start with 
               a comment character (if any)... */
            if (fileLine.equals("") || fileLine.startsWith(";") || fileLine.startsWith("#")) {
                continue;
            }
            /* Valid data line we want...add it to the list.
               Here we split the data line into a String array
               then we use the Arrays.asList() method to convert
               it to a List then we add that List to our 2D List. 
               All done in one line of code.  */
            list.add(Arrays.asList(fileLine.split("\\s+")));
        }
        sc.close();     // Close the reader.
    }
    catch (FileNotFoundException ex) {
        System.err.println(ex.getMessage());
    }
    return list;
}

并针对示例数据文件使用此方法:

// Read the file data and place it all into a 2D List
List<List<String>> list = readDataFile("10by10.txt");

// Get the Header Column Names from first ArrayList
String[] headerData = list.get(0).toArray(new String[0]);   

// The 2D Object Array to hold raw File Data
Object[][] data = new Object[list.size() - 2][headerData.length];      
for(int i = 1; i < list.size() - 1; i++) {
    for (int j = 0; j < list.get(i).size(); j++) {
        if (j == 0) {
            data[i - 1][j] = list.get(i).get(j);
        }
        else {
            data[i - 1][j] = Integer.parseInt(list.get(i).get(j));
        }
    }
}

// Last data line in file is the DEMAND Values
String[] tmp = list.get(list.size() - 1).toArray(new String[0]);
int[] demandData = new int[tmp.length - 1];
for (int i = 1; i < tmp.length; i++) {
    demandData[i - 1] = Integer.parseInt(tmp[i]);
}

if (data != null) {
    // Header Information:
    System.out.println("Header Column Names:\n"
            + Arrays.toString(headerData) + "\n");

    // The Actual Data:
    System.out.println("File Data:");
    for (int i = 0; i < data.length; i++) {
        System.out.println(Arrays.toString(data[i]));
    }

    // The Demand Information:
    System.out.println("\nDemand Values For Each Row:\n"
            + Arrays.toString(demandData) + "\n");
}

控制台窗口的输出将与上面显示的相同。