首页 > 解决方案 > 如何正确初始化从输入文件读取的整数 ArrayList 的 ArrayList

问题描述

我需要用这种格式解析一个输入文件。输入文件可以是任意大小,所以我决定使用列表而不是数组。解析数据后,我需要将其存储为数组。它代表 RGB 值。例如,这个片段是一个 2x2 像素的图像。

[251,255,128],[132,244,121]
[125,156,155],[157,200,090]

公共类 RGBFileReader {

public static void main(String[] args) {
    String filename;
    filename = args[0];
    new RGBFileReader().ReadRGBfile(filename);
} // end main method block

// declare the class constructor, pass filename parameter and initialize variables
public void ReadRGBfile (String filename) {
    int rowCount = 0;
    int columnCount = 0;
    int columnIndex = 0;

    //2D List = ArrayList of an ArrayList of Integers. ArrayList stores Objects not "ints"!
    ArrayList<ArrayList<Integer>> rgbArrayList = new ArrayList<ArrayList<Integer>>();

    try {
        //confirm current working directory for I/O files
        System.out.println("parsing input file at path: " + new File(".").getAbsoluteFile()+ filename);

        // pass the path to the file as a parameter 
        File file = new File("input/" + filename); 
        Scanner myScanner = new Scanner(file);

        // pattern match to sequence of comma delimited integers inside square brackets: [+/-int,+/-int,+/-int]    
        // -? = once or not at all, and minus sign handles negative numbers (although not strictly needed in this context)
        String patternToMatch = "\\[(-?\\d+),(-?\\d+),(-?\\d+)\\]";
        Pattern pattern = Pattern.compile(patternToMatch);

        // [\\d] = any digit, note need a second backslash to escape first backslash which is a java escape character
        // +     = 1 or more occurrences
        String innerpatternToMatch = "(\\d+)";
        Pattern innerpattern = Pattern.compile(innerpatternToMatch);

        while (myScanner.hasNextLine()) { // while loop to scan each line of input file
            ArrayList<Integer> singleRow = new ArrayList<Integer>();
            columnIndex = 0;
            System.out.println("rowCount: " + rowCount);
            String line = myScanner.nextLine();
            Matcher matcher = pattern.matcher(line);

            while (matcher.find()) { // outer while to parse groups of brackets

                System.out.println("columnCount: " + columnCount);
                String outerline = matcher.group();
                System.out.println("outerline: " + outerline);
                Matcher innermatcher = innerpattern.matcher(outerline);

                while (innermatcher.find()) { // inner while to parse triplets within brackets
                    String innerline = innermatcher.group();
                    System.out.println("innerline: " + innerline);
                    singleRow.add(Integer.valueOf(innermatcher.group())); //add triplets one at a time to inner List "oneRow"
                    System.out.println("singleRow = " + singleRow);
                    columnIndex++;
                } //end inner inner while
                columnCount = columnIndex;

            } // end outer while
            rgbArrayList.add(singleRow);  // add the oneRow of triplets, to the outer List "twodimArrayList"
            System.out.println("rgbArrayList dump using toString(): " + rgbArrayList.toString());
            System.out.println("\n");
            rowCount++;

        } // end scanner while loop
        myScanner.close();
        System.out.println("scanner is closed...");

    } // end Try block
    catch (FileNotFoundException e) {
        System.err.println("Could not open RGB input file: check it exists, is in the file path, or has correct format.");
    } //end catch block

    //sanity check for correct values of rowCount and columnCount
    System.out.println("\n");
    System.out.println("rowCount: " + rowCount);
    System.out.println("columnCount: " + columnCount);

    // Parsing of input file complete, now declare int[][] array
    int [][] rgbArray = new int [rowCount][columnCount];

    // check for expected values properly stored in ArrayList 
    System.out.println("\n"); 
    System.out.println("List<Integer> rgbArrayList values using iterator" );
    Iterator<ArrayList<Integer>> iterator = rgbArrayList.iterator();
    while (iterator.hasNext()) {
        System.out.println(iterator.next());
    }

    //Initialize the int [][] Array using values from the ArrayList
    System.out.println("\n");
    for (int row = 0; row < rowCount; row++) {
        for (int col = 0; col < columnCount; col++) {
            rgbArray[row][col] = rgbArrayList.get(row).get(col).intValue();
        } // end inner for loop
    } // end outer for loop

    System.out.println("rgbArray values"); 
    for (int i = 0; i < rowCount; i++) {
        System.out.println(Arrays.toString(rgbArray[i]));
    } // end inner loop

} // end method ReadRGBfile

} // 结束类

标签: javaregexarraylistmultidimensional-arrayinteger

解决方案


实际上并没有 2D ArrayList 这样的东西。您正在创建一个列表列表,这意味着外部列表的每个元素都必须是新的ArrayList<Integer>,并且所有内部列表不需要彼此大小相同。尝试将您的singleRow声明向下移动到 while 循环内并删除singleRow.clear();

附带说明一下,添加到列表时不必使用索引。twodimArrayList.add(singleRow);将添加到列表的末尾。


推荐阅读