user6893697
user6893697

Reputation: 21

Java: How can I read and store them in array by a new line in ArrayList?

Here is what my .txt file looks like (but more than 100 elements per line and more than 100 lines):

-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

What I want to do is read this .txt file and store them in Arryalist. The problem is when I read and store this data, they put all of this in the same array (I want them to store in 2 arrays split by a line).

Here is my code:

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

Any suggestion for making this works?

Upvotes: 1

Views: 2894

Answers (6)

Stuart Marks
Stuart Marks

Reputation: 132370

I'm assuming that the number of floats on each line might differ from line to line. If they're all the same, I'd suggest reading them into one big list and then splitting it into sublists.

But if you want to have all the floats on a line be in a single list, it seems like the best approach is to read the file line by line. Then, split each line into tokens, convert to float, and collect the results into a list. The overall result will be a list of list of float. This is pretty easy to do with Java 8 streams:

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());
    }
}

Note the use of Files.lines to get a stream of lines, and also note the use of try-with-resources on the resulting stream.

If you have Java 9, you can simplify this a tiny bit by using Scanner instead of Pattern.splitAsStream to parse the tokens on each line:

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());
    }
}

Upvotes: 0

Anant Binjola
Anant Binjola

Reputation: 3

Each line can be stored as an ArrayList and each ArrayList inside another ArrayList creating a 2-Dimensional ArrayList of Float type. Read each line using java.util.Scanner.nextLine() and then parse each line for float value. I have used another scanner to parse each line for float values. After parsing, store float values into a tmp ArrayList and add that list to the major List. Be sure to close the local scanner inside the while itself.

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();
        }        
    }
}

Upvotes: 0

Sudhakar
Sudhakar

Reputation: 3180

Read the file once with Files.readAllLines method. And split it by spaces

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

Upvotes: 0

Jay Smith
Jay Smith

Reputation: 2480

You can read line by line and split it by spaces . Working and tested code:

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

You can also read float values by regex.

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();

Upvotes: 0

Ashraful Islam
Ashraful Islam

Reputation: 12830

First read line by line, then for each line read each float.

Try This :

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

Output :

[[-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]]

Upvotes: 0

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521093

I might go about this by just reading in each line in its entirety, and then splitting on whitespace to access each floating point number. This gets around the issue of having to distinguish spaces from line separators.

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();
    }
}

Here is a demo showing that the logic works for a single line of your input file. Note that I call String#trim() on each line before splitting it, just in case there is any leading or trailing whitespace which we don't want.

Rextester

Upvotes: 1

Related Questions