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

时间:2018-11-09 19:48:25

标签: java list arraylist

我正在尝试读取一个包含图的邻接表的文件。该文件如下所示:

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

每行都是一个链表,其长度不同于其他行。到目前为止,我已经尝试过:

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!");
}

但是它不起作用,因为当我尝试打印整个矩阵时会显示错误(NullPointerException)。如何正确读取此文件?

3 个答案:

答案 0 :(得分:1)

已编辑 我复制了您的代码,初始化了列表,添加了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();
}

答案 1 :(得分:1)

为此,您确实应该使用来自“新” 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(" ")));
}

这几行用main()方法包装,完成了所有工作。

这很简单:

  • 首先读取所有行,这将返回一个列表。从文件的行创建流。此调用将引发IOException,因此,如果您确实想通过打印到标准输出来处理异常,则可能需要将其包装在示例中。
  • 第二行将每一行拆分为一个数组。
  • 第三行map(Arrays::asList)从每个数组创建一个List
  • 最后将列表收集到列表列表中。

打印部分同样简单。它在列表列表上进行流式处理,并使用平面映射将子列表“平化”为一个流。然后它将元素连接到一个字符串,并用" "隔开,并打印出来。

与原始代码相比,这容易出错,几乎不会出错。当然,它在一些次要方面有所不同,例如toList()不保证您会获得ArrayList,但这并不重要。

答案 2 :(得分:1)

在使用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);
}

这会根据文件中的数据提供以下输出,

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