【问题标题】:Read file by word, Scanner逐字读取文件,扫描仪
【发布时间】:2018-03-18 04:40:57
【问题描述】:

我有一个txt文件,其中每一行包含两个单词,例如:

USA 321
France 1009
...
Germany 902

如何在二维数组中逐字读取此文件?我有:

List<List<String>> temps = new ArrayList<>();
Scanner dataScanner = new Scanner(dataFile);

while (dataScanner.hasNextLine()) {
    Scanner rowScanner = new Scanner(dataScanner.nextLine());
    temps.add(new ArrayList<>(2));

    while (rowScanner.hasNextLine()) {
        ...
    }
}

【问题讨论】:

  • 你必须使用扫描仪的行吗?如果没有,请使用String.split() 将行拆分为单词。
  • 如果你必须对行使用扫描器,不要使用rowScanner.hasNextLine();它只包含一行。使用hasNext()(和next())从行中获取单个单词。此外,如果您确定每行总是正好有 2 个单词,您可以将结构设为 List&lt;String[2]&gt;

标签: java arrays file arraylist java.util.scanner


【解决方案1】:

假设您的代码有效,我会这样做

List<List<String>> temps = new ArrayList<>();
Scanner dataScanner = new Scanner(dataFile);

while (dataScanner.hasNextLine()) {
    String[] data = dataScanner.nextLine().split(" ");
    temps.add(new ArrayList<>(Arrays.asList(data[0],data[1]));
}

这将获取当前行并将其拆分为空格字符。 然后它会创建一个包含这两个元素的列表并将其添加到您的临时列表中

【讨论】:

    【解决方案2】:

    如果你想绝对使用扫描仪:

    List<List<String>> temps = new ArrayList<>();
            Scanner dataScanner = new Scanner("a b\nc d\ne f\n");
    
            while (dataScanner.hasNextLine()) {
                Scanner rowScanner = new Scanner(dataScanner.nextLine());
                List<String> datas=new ArrayList<>(2);
                temps.add(datas);
    
                while (rowScanner.hasNext("[^\\s]+")) {
                    datas.add(rowScanner.next("[^\\s]+"));
                }
            }
    

    【讨论】:

      【解决方案3】:

      我的建议是始终在不同的功能中分离不同的功能。代码变得更易于阅读、更易于维护可重用

      public static List<String> readFileLineByLine(String file) {
         List<String> lines = new ArrayList<>();
         Scanner scanner = new Scanner(file);
         while (scanner.hasNextLine()) {
            temps.add(scanner.nextLine());
         }
         return lines;
      }
      
      public static List<MyData> parseLines(List<String> lines) {
         List<MyData> list = new ArrayList<>();
         for (String line : lines) {
            String[] data = line.split(" ");
            list.add(new MyData(data[0], data[1]));
         }
         return list;
      }
      

      (如果需要,请使用List&lt;String&gt; 作为MyData

      【讨论】:

      • 同意你的看法。在你的代码中,我应该添加一个函数来只读取一个 MyData 以增加可维护性和可重用性
      【解决方案4】:

      我是 Scanner 的忠实粉丝,但在这种情况下,您可以通过逐行阅读并使用 String.split 来获得。使用流这变得非常简单。如果你想读入一个二维数组,你可以这样做:

          try (Stream<String> lines = Files.lines(Paths.get(FILENAME), UTF_8)) {
              String[][] result = lines.map(s -> s.split("\\s+"))
                                       .toArray(String[][]::new);
          }
      

      或者如果你想要嵌套列表,你可以这样做:

          try (Stream<String> lines = Files.lines(Paths.get(FILENAME), UTF_8)) {
              List<List<String>> result = lines.map(s -> s.split("\\s+"))
                                               .map(Arrays::asList)
                                               .collect(toList());
              System.out.println(result);
          }
      

      【讨论】:

        猜你喜欢
        • 2012-11-02
        • 1970-01-01
        • 2013-12-04
        • 1970-01-01
        • 2012-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多