扫描文本文件到 ArrayList<ArrayList<String>>

Scanning text file to ArrayList<ArrayList<String>>

我正在尝试将文本文件读入 ArrayList<ArrayList<String>>

文件看起来像:

A D E F
B A F
C A B D
D B C
E B C D F
F A B D
G
H A D F

以下是我的一段代码:

private static void registerPages() throws IOException {
        Scanner input = new Scanner(new File(webPath));
        //input.useDelimiter(" ");


        ArrayList<ArrayList<String>> arrayList = new ArrayList<>();
        ArrayList<String> row = new ArrayList<>();
        String tempStr;
        String[] tempArr;

        while (input.hasNextLine())
        {
            row.clear();
            tempStr = input.nextLine(); //get row in string
            tempArr = tempStr.split(" "); //split string into strings[]
            Collections.addAll(row, tempArr); //add each strings[] to arrayList
            arrayList.add(row); //add arrayList to arrayList
        }

        System.out.println("arrayList:\n" + arrayList);

    }

输出为:

arrayList:
[[H, A, D, F], [H, A, D, F], [H, A, D, F], [H, A, D, F], [H, A, D, F], [H, A, D, F], [H, A, D, F], [H, A, D, F]]

想要的输出是:

arrayList:
[[A, D, E, F], [B, A, F], [C, A, B, D], [D, B, C], [E, B, C, D, F], [F, A, B, D], [G], [H, A, D, F]]

仅供参考, 这个文本文件应该是一个网络图。第一个词是网页。同一行中的下一个词是链接到该网页的其他网页(in-links)。最终,我应该编写 'Page Rank' 算法。

提前谢谢你。

public static void main(String[] args) {
    File file = new File("webpath.txt"); // Your text file
    ArrayList<List<String>> arrayList = new ArrayList<>();

    try(Scanner sc = new Scanner(file)) {
        List<String> arrayRow = new ArrayList<>();

        while (sc.hasNextLine()) {
            String line = sc.nextLine(); // Retrieve 1 line from the text file
            String[] data = line.split(" "); // Splitting the characters and storing them
            arrayRow = Arrays.asList(data); // Converting array to List
            arrayList.add(arrayRow); // Adding row of characters to the final arraylist
        }
    }
    catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    // Looping through the result arraylist
    for (List<String> array : arrayList) {
        for(String item : array) {
            System.out.print(item + " ");
        }
        System.out.println();
    }
}

问题是您正在重复使用并添加到 arrayList 表示 row 的相同列表实例(因此它打印 N 次 current/last 状态)。您应该为每一行创建 new 列表,然后将其添加到您的主列表中。

所以只需将 ArrayList<String> row = new ArrayList<>(); 移动到你的循环中,然后。

尝试在每次迭代中实例化行,而不是使用 row.clear()row = new ArrayList<>()

提示:
您只创建了一次 row。所以 arrayList 中的所有项目持有者都指向同一个内存块。您必须创建新实例(内存中的真实对象),以便它们可以保存不同的值。

您在 arrayList 中多次添加同一行。每次修改同一行,最后多次插入最后一行。您必须每次都创建新行:put line ArrayList row = new ArrayList<>(); 代替 row.clear();

public static void main(String[] args) throws IOException {
    registerPages(new FileReader("test.txt"));
}

private static void registerPages(Reader reader) throws IOException {
    Scanner input = new Scanner(reader);
    List<List<String>> arrayList = new ArrayList<>();

    while (input.hasNextLine()) {
        List<String> row = new ArrayList<>();
        Collections.addAll(row, input.nextLine().split(" "));
        arrayList.add(row);
    }

    System.out.println("arrayList:\n" + arrayList);
}

输出:

arrayList:
[[A, D, E, F], [B, A, F], [C, A, B, D], [D, B, C], [E, B, C, D, F], [F, A, B, D], [G], [H, A, D, F]]

您的代码存在的问题是您一直在同一个 row 实例上运行。主 arrayList 实例多次包含相同的 List 实例,并且您不断地重新添加相同的实例,每次都为它清除和设置新数据。这就是为什么您在 arrayList 的所有条目上看到相同结果的原因 - 它基本上多次包含相同的列表。这是因为列表是一个可变对象——它的状态可以修改,将它传递给另一个数据结构不会阻止它反映在另一个数据结构中对其所做的更改。通过传递一个对象(例如,给另一个方法)并不意味着你正在复制它的内容,你正在与另一个方法共享该对象。两者看到的是同一个对象 - 共享对象的更改对两者都是可见的。