简体   繁体   English

如何从文件中读取ArrayList的列表?

[英]How to read a list of ArrayLists from file?

I'm trying to read a file which contains adjacency list of a graph. 我正在尝试读取一个包含图的邻接表的文件。 The file looks like this: 该文件如下所示:

1 2 3 5
2 4
3 1 5
4 
5 2 4

Each line is a linked list with some length different than other lines. 每行是一个链表,其长度不同于其他行。 So far I tried this: 到目前为止,我已经尝试过了:

private static List<ArrayList<String>> adj;

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

int i = 0;
try {
    Scanner input = new Scanner(new BufferedReader(new FileReader(fileName)));
    //BufferedReader input = new BufferedReader(new FileReader(fileName));

    String line;
    while (input.hasNextLine()){
        i++;
        String[] cols = input.nextLine().trim().split(" ");
        for (String c : cols){
            rows.add(c);
        }
        adj.add(rows);
    }

    //print the matrix
    for (List<String> list : adj) {
        for (String str : list) {
            System.out.print(str + " ");
        }
        System.out.println();
    }
}
catch (IOException e){
    System.out.println("Error reading input file!");
}

but it doesn't work, because it shows an error (NullPointerException) when I try to print the whole matrix. 但它不起作用,因为当我尝试打印整个矩阵时会显示错误(NullPointerException)。 How can I read this file properly? 如何正确读取此文件?

Edited I reproduced your code, made the initializtion of the list, added try/catch and added the printing code and this is working fine: 编辑后,我复制了您的代码,对列表进行了初始化,添加了try / catch并添加了打印代码,这工作正常:

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

int i = 0;

Scanner input = null;
try {
    input = new Scanner(new BufferedReader(new FileReader(fileName)));
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

String line;
while (input.hasNextLine()) {
    ArrayList<String> rows = new ArrayList<String>();
    i++;
    String[] cols = input.nextLine().trim().split(" ");
    for (String c : cols) {
        rows.add(c);
    }
    adj.add(rows);
}

for (ArrayList<String> list : adj) {
    for (String s : list) {
        System.out.print(s + " ");
    }
    System.out.println();
}

You really should use methods from the "new" Java NIO (introduced in Java 7) together with streams (introduced in Java 8) for this: 为此,您实际上应该使用来自“新” Java NIO(在Java 7中引入)的方法以及流(在Java 8中引入)。

public void readLinesExample(String fileName) throws IOException {
  List<List<String>> adj = Files.readAllLines(Paths.get(fileName)).stream()
      .map(row -> row.split(" "))
      .map(Arrays::asList)
      .collect(toList());

  System.out.println(adj.stream().flatMap(Collection::stream).collect(joining(" ")));
}

These few lines does all the job, wrapped in a main() method. 这几行完成了所有工作,并包装在main()方法中。

It is pretty straightforward: 这很简单:

  • First read all the lines, which returns a list. 首先阅读所有行,这将返回一个列表。 Create a stream from the rows of the file. 从文件的行创建流。 This call throws the IOException so you might want to wrap this in an example if you truly want to handle the exception by printing to standard out. 该调用将引发IOException因此,如果您确实想通过打印到标准输出来处理异常,则可能需要将其包装在示例中。
  • The second line splits each row to an array. 第二行将每一行拆分为一个数组。
  • The third line, map(Arrays::asList) creates a List from each array. 第三行map(Arrays::asList)从每个数组创建一个List
  • Finally the lists are collected to a list of lists. 最后,列表被收集到列表列表中。

The print part is equally simple. 打印部分同样简单。 It streams over the list of lists, and uses flat map to "flatten" the sub lists to one stream. 它在列表列表上进行流式处理,并使用平面映射将子列表“平化”为一个流。 It then joins the elements to a string, separated by " " , and prints it. 然后将元素连接到一个字符串,并用" "分隔,并进行打印。

This is much less error prone than your original code, you can hardly do wrong. 与原始代码相比,这不容易出错,您几乎不会做错任何事情。 Of course, it differs in some minor ways, like toList() not guaranteeing that you get an ArrayList , but that is rarely important. 当然,它在一些次要方面有所不同,例如toList()不能保证您得到ArrayList ,但这并不重要。

In another approach using Java 8, you can simplify your code and write something like this to read the file containing your adjacency list of a graph or any similar data. 在使用Java 8的另一种方法中,您可以简化代码并编写类似的内容以读取包含图形或任何类似数据的邻接表的文件。

public static void printGraph() throws Exception {
    List<String> numberList = Files.readAllLines(Paths.get("graph.txt")); // reads all lines in one shot into a List<String>

    List<List<Integer>> listOfIntegerList = new ArrayList<List<Integer>>();

    for (String s : numberList) { // for each line containing numbers, stores them into a List<Integer>
        listOfIntegerList.add(Arrays.stream(s.split("\\s+")).map(Integer::parseInt).collect(Collectors.toList()));
    }

    System.out.println(listOfIntegerList);
}

This gives following output as per the data present in your file, 根据文件中存在的数据,这将提供以下输出,

[[1, 2, 3, 5], [2, 4], [3, 1, 5], [4], [5, 2, 4]]

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

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