Reputation: 21
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
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
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
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
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
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
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.
Upvotes: 1