【问题标题】:Java: How can I read and store them in array by a new line in ArrayList?Java:如何通过 ArrayList 中的新行读取它们并将它们存储在数组中?
【发布时间】:2017-06-06 06:28:01
【问题描述】:

这是我的 .txt 文件的样子(但每行超过 100 个元素和超过 100 行):

-0.89094    -0.86099    -0.82438    -0.78214    -0.73573    -0.68691    -0.63754
-0.42469    -0.3924     -0.36389    -0.33906    -0.31795    -0.30056    -0.28692

我想要做的是读取这个 .txt 文件并将它们存储在 Arryalist 中。问题是当我读取和存储这些数据时,他们将所有这些都放在同一个数组中(我希望它们存储在由一行分割的 2 个数组中)。

这是我的代码:

public class ReadStore {
    public static void main(String[] args) throws IOException {

    Scanner inFile = new Scanner(new File("Untitled.txt")).useDelimiter("\\s");
    ArrayList<Float> temps = new ArrayList<Float>();

    while (inFile.hasNextFloat()) {
      // find next line
      float token = inFile.nextFloat();
      temps.add(token);

    }

    inFile1.close();

    Float [] tempsArray = temps.toArray(new Float[0]);
    for (Float s : tempsArray) {
      System.out.println(s);
    } 
  }

有什么建议可以让它工作吗?

【问题讨论】:

  • 如果您选择构建 .txt 文件的方式,您应该改用 .csv 文件。

标签: java arraylist java.util.scanner toarray


【解决方案1】:

我可以通过完整地读取每一行,然后在空格上拆分以访问每个浮点数来解决这个问题。这解决了必须区分空格和行分隔符的问题。

public class ReadStore {
    public static void main(String[] args) throws IOException {
        Scanner inFile = new Scanner(new File("Untitled.txt"));
        ArrayList<Float> temps = new ArrayList<Float>();

        while (inFile.hasNextLine()) {
            String line = inFile.nextLine();
            String[] nums = line.trim().split("\\s+");
            for (String num : nums) {
                float token = Float.parseFloat(num);
                temps.add(token);
            }
            Float [] tempsArray = temps.toArray(new Float[0]);
            for (Float s : tempsArray) {
                System.out.println(s);
            }
        }

        inFile.close();
    }
}

这是一个演示,显示该逻辑适用于输入文件的单行。请注意,在拆分之前,我会在每一行上调用String#trim(),以防万一有任何我们不想要的前导或尾随空格。

Rextester

【讨论】:

    【解决方案2】:

    首先逐行读取,然后每行读取每个浮点数。

    试试这个:

    public static void main(String[] args) throws IOException {
        Scanner inFile = new Scanner(new File("Untitled.txt"));
        List<List<Float>> temps = new ArrayList<>();
    
        while (inFile.hasNextLine()) {
            List<Float> data = new ArrayList<>();
    
            Scanner inLine = new Scanner(inFile.nextLine());
            while (inLine.hasNextFloat()) {
                data.add(inLine.nextFloat());
            }
            inLine.close();
    
            temps.add(data);
        }
    
        inFile.close();
    
        Float[][] dataArray = new Float[temps.size()][];
    
        for (int i = 0; i < dataArray.length; i++) {
            dataArray[i] = temps.get(i).toArray(new Float[temps.get(i).size()]);
        }
    
        System.out.println(Arrays.deepToString(dataArray));
    }
    

    输出:

    [[-0.89094, -0.86099, -0.82438, -0.78214, -0.73573, -0.68691, -0.63754], [-0.42469, -0.3924, -0.36389, -0.33906, -0.31795, -0.30056, -0.28692]]
    

    【讨论】:

      【解决方案3】:

      您可以逐行阅读并用空格分隔。工作和测试代码:

      public static void main(String[] args) throws IOException {
      
              Scanner inFile = new Scanner(new File("C:\\Untitled.txt"));
              ArrayList<String[]> temps = new ArrayList<>();
      
              while (inFile.hasNextLine()) {
                  // find next line
                  String line = inFile.nextLine();
                  String[] floats = line.split("\\s+");
                  temps.add(floats);
              }
      
              inFile.close();
      
              temps.forEach(arr -> {
                  System.out.println(Arrays.toString(arr));
              });
          }
      

      您还可以通过正则表达式读取浮点值。

      Scanner inFile = new Scanner(new File("C:\\Untitled.txt"));
              ArrayList<Float> temps = new ArrayList<>();
      
              while (inFile.hasNext("-\\d\\.\\d+")) {
                  // find next line
                  String line = inFile.next();
                  temps.add(Float.valueOf(line));
              }
      
              inFile.close();
      

      【讨论】:

        【解决方案4】:

        使用 Files.readAllLines 方法读取文件一次。并用空格分割

        import java.io.File;
        import java.io.IOException;
        import java.nio.file.Files;
        import java.util.ArrayList;
        import java.util.stream.Collectors;
        
        public class Test {
            public static void main(String[] args) {
                String readFileContent = readFileContent(new File("Test.txt"));
                ArrayList<Float> temps = new ArrayList<Float>();
                String[] split = readFileContent.split("\\s+");
                for (String num : split) {
                     float token = Float.parseFloat(num.trim());
                     temps.add(token);
                }
        
                Float [] tempsArray = temps.toArray(new Float[0]);
                for (Float s : tempsArray) {
                    System.out.println(s);
                }
            }
        
            private static String readFileContent(File file) {
                try {
                    return Files.readAllLines(file.toPath()).stream().collect(Collectors.joining("\n"));
                } catch (IOException e) {
                    System.out.println("Error while reading file " + file.getAbsolutePath());
                }
                return "";
            }
        }
        

        【讨论】:

          【解决方案5】:

          每一行都可以存储为一个ArrayList,每个ArrayList 都可以存储在另一个ArrayList 中,从而创建一个浮点类型的2-Dimensional ArrayList。 使用 java.util.Scanner.nextLine() 读取每一行,然后解析每一行的浮点值。我使用了另一个扫描仪来解析每一行的浮点值。 解析后,将浮点值存储到 tmp ArrayList 并将该列表添加到主要列表。 请务必在 while 内部关闭本地扫描程序。

          import java.io.File;
          import java.io.IOException;
          import java.util.ArrayList;
          import java.util.Scanner;
          
          public class ReadStore {
              public static void main(String[] args) throws IOException {
                  //Input File
                  Scanner inFile =new Scanner(new File("Untitled1.txt")).useDelimiter("\\s");
                  //Major List (2-D ArrayList)
                  ArrayList<ArrayList<Float>> list = new ArrayList<ArrayList<Float>>();
                  //Reading Each Line
                  while (inFile.hasNextLine()) {
                      //tmp ArrayList
                      ArrayList<Float> arr = new ArrayList<Float>();
          
                      String line = inFile.nextLine();
                      //local scanner to be used for parsing
                      Scanner local = new Scanner(line);
                      //Parsing line for flat values
                      while(local.hasNext()){
                          if(local.hasNextFloat()){
                              float token = local.nextFloat();
                              arr.add(token); 
                          }   
                      }
                      //closing local Scanner
                      local.close();
                      //Adding to major List
                      list.add(arr);
                  }
                  inFile.close();
                  //Display List values
                  for(ArrayList<Float> arrList:list){
          
                      for(Float f : arrList){
                          System.out.print(f + " ");
                      }
                      System.out.println();
                  }        
              }
          }
          

          【讨论】:

          • PS:二维数组可以通过任何方式创建。不一定是 ArrayList
          【解决方案6】:

          我假设每行上的浮点数可能因行而异。如果它们都相同,我建议将它们读入一个大列表,然后将其拆分为子列表。

          但是如果你想让一行上的所有浮点数都在一个列表中,最好的方法似乎是逐行读取文件。然后,将每一行拆分为标记,转换为浮点数,并将结果收集到一个列表中。总体结果将是浮动列表的列表。使用 Java 8 流很容易做到这一点:

          static List<List<Float>> readData() throws IOException {
              Pattern pat = Pattern.compile("\\s+");
              try (Stream<String> allLines = Files.lines(Paths.get(filename))) {
                  return allLines.map(line -> pat.splitAsStream(line)
                                                 .map(Float::parseFloat)
                                                 .collect(Collectors.toList()))
                                 .collect(Collectors.toList());
              }
          }
          

          注意使用Files.lines 来获取行流,并注意在结果流上使用try-with-resources。

          如果您有 Java 9,则可以通过使用 Scanner 而不是 Pattern.splitAsStream 来解析每一行上的标记,从而稍微简化一下:

          static List<List<Float>> readData9() throws IOException {
              try (Stream<String> allLines = Files.lines(Paths.get(filename))) {
                  return allLines.map(Scanner::new)
                                 .map(sc -> sc.tokens()
                                              .map(Float::parseFloat)
                                              .collect(Collectors.toList()))
                                 .collect(Collectors.toList());
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2021-06-09
            • 1970-01-01
            • 2013-05-09
            • 1970-01-01
            • 2019-04-30
            • 1970-01-01
            • 1970-01-01
            • 2017-10-13
            • 1970-01-01
            相关资源
            最近更新 更多