All the examples that i have seen involve specifying the number of rows and columns at the start of the file but the method I'm working on reads a file with the following:
1.0 2.0
3.0 4.0
and using this data creates a 2d array and stores it without specifying the number of rows and columns.
Here's the code I have written:
public static double[][] readMatrixFrom(String file) throws FileNotFoundException {
Scanner input = new Scanner(new FileReader(file));
int rows =0;
int columns =0;
while(input.hasNextLine()){
String line = input.nextLine();
rows++;
columns = line.length();
}
double[][] d = new double[rows][columns]
return d;
}
I'm unsure of how to add these values now that I have created the 2d array. i tried this but got an InputMismatchException.
Scanner s1 = new Scanner(file);
double[][] d = new double[rows][columns]
for (int i= 0;i<rows;i++) {
for (int j= 0;i<rows;j++) {
d[i][j] = s1.nextDouble();
}
}
if you just want to use the basic arrays you can achieve it with something like
Scanner input = new Scanner(new FileReader(file));
int row=0;
int col =0;
String s="";
//count number of rows
while(input.hasNextLine()) {
row++;
s=input.nextLine();
}
//count number of columns
for(char c: s.toCharArray()) {
if(c==' ')
col++;
}
col++; // since columns is one greater than the number of spaces
//close the file
input.close();
// and open it again to start reading it from the begining
input = new Scanner(new FileReader(file));
//declare a new array
double[][] d = new double[row][col];
int rowNum=0;
while(input.hasNextLine()) {
for(int i=0; i< col; i++) {
d[rowNum][i]= input.nextDouble();
}
rowNum++;
}
However if you prefer to use java collection you can avoid reading the file again. Just store the strings in a list and iterate over the list to extract elements from it.
Based on your input, Your columns = line.length(); is returning 7 rather than 2 as it returns the String length.
Hence try calculating the no of columns in the row columns = line.split(" ").length;
Also while trying to read your input you were using index i for the 2nd for-loop. It should be like below,
for (int i= 0;i<rows;i++) {
for (int j= 0;j<columns;j++) {
d[i][j] = s1.nextDouble();
}
}
In order to work with arrays of unknown size you should read the data into a Collection (such as a List). However, Collection(s) only work with the wrapper-types; so you will need to copy the elements back into an array of double(s) if that is what you really need. Something like,
public static double[][] readMatrixFrom(String file) throws FileNotFoundException {
Scanner input = new Scanner(new FileReader(file));
List<List<Double>> al = new ArrayList<>();
while (input.hasNextLine()) {
String line = input.nextLine();
List<Double> ll = new ArrayList<>();
Scanner sc = new Scanner(line);
while (sc.hasNextDouble()) {
ll.add(sc.nextDouble());
}
al.add(ll);
}
double[][] d = new double[al.size()][];
for (int i = 0; i < al.size(); i++) {
List<Double> list = al.get(i);
d[i] = new double[list.size()];
for (int j = 0; j < d[i].length; j++) {
d[i][j] = list.get(j);
}
}
return d;
}
Which I tested by creating a file in my home folder with your contents and running it like so
public static void main(String[] args) {
String file = System.getProperty("user.home") + File.separator + "temp.txt";
try {
System.out.println(Arrays.deepToString(readMatrixFrom(file)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
And I get (as I assume you wanted)
[[1.0, 2.0], [3.0, 4.0]]
I have this CSV file:
World Development Indicators
Number of countries,4
Country Name,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014
Bangladesh,6.28776238,13.20573922,23.46762823,30.16828408,34.35334451,44.94535882,55.19256723,62.82023906,74.42964608,80.03535051
"Bahamas, The",69.21279415,75.37855087,109.340767,102.7875065,101.2186453,118.8292307,81.5628489,80.65383375,76.05187427,82.29635806
Brazil,46.31418452,53.11025849,63.67475185,78.5549801,87.54187651,100.8810115,119.0023853,125.0018521,135.3050481,138.9514906
Germany,94.55486999,102.2828888,115.1403608,126.5575074,126.2280577,106.4836959,109.6595675,111.5940398,120.9211651,120.4201855
I am trying to store countries' data(double once) into a matrix(double[][]). Here is the code that I have so far:
public double[][] getParsedTable() throws IOException {
double[][] table = new double[4][10];
String row;
int indexRow = 0;
int indexColumn = 0;
BufferedReader br = new BufferedReader(new FileReader(fileName));
br.readLine();
br.readLine();
String line = br.readLine();
while(line != null && !line.isEmpty()){
line = br.readLine();
String[] array = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
for(int i = 1; i < array.length; i++){
table[indexRow][indexColumn] = Double.parseDouble(array[i]);
indexColumn++;
}
indexColumn = 0;
indexRow++;
}
System.out.print(Arrays.deepToString(table));
return table;
}
I am getting an arror : NullPointerException at:
String[] array = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
I cant figure out why. I tried different combinations. nothing seems to work. It seems to pick up the numbers from the CSV file and store them, but when I call:
System.out.print(Arrays.deepToString(table));
it does not print out anything, hence I cant check if its stored properly or not. Could you tell me: 1. Why I am getting an error. 2. Why System.out.println does not print out an array. Thanks
If we assume that name of a country will not contain a digit and country name and numbers will be only comma separated, then following can be done without regex. I have changed file reading a little bit because it can run into issues.
public double[][] getParsedTable() throws IOException {
double[][] table = new double[4][10];
int indexRow = 0;
int indexColumn = 0;
BufferedReader br = new BufferedReader(new FileReader(fileName));
br.readLine(); // ignore first line
br.readLine(); // ignore second line
br.readLine(); // ignore third line (contains title)
String line;
while (true) {
line = br.readLine();
if (line == null) break; // end of file reading
int index = 0;
while (true) {
index = line.indexOf(",", index) + 1;
if (Character.isDigit(line.charAt(index))) {
break;
}
}
// from index, line is expected to contain comma separated numbers
String[] array = line.substring(index).split(",");
for (int i = 0; i < array.length; i++) {
table[indexRow][indexColumn] = Double.parseDouble(array[i]);
indexColumn++;
}
indexColumn = 0;
indexRow++;
}
System.out.print(Arrays.deepToString(table));
return table;
}
In the csv, first 3 lines are not real country's data. So read in line-4 before while loop starts.
In while loop, first finish the processing of line string first. Eg: regular expression check & assign split data into table.
Then only read in next line at end of while loop, to be processed in next iteration.
Feel free to try this out:
public double[][] getParsedTable() throws IOException {
double[][] table = new double[4][10];
int indexRow = 0;
int indexColumn = 0;
// check whether you need to handle any exception for this
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = null;
try {
// line 1-3 are not real country's data
br.readLine();
br.readLine();
br.readLine();
// first country data begin at line 4
line = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
while (line != null && !line.isEmpty()) {
String[] array = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
for (int i = 1; i < array.length; i++) {
table[indexRow][indexColumn] = Double.parseDouble(array[i]);
indexColumn++;
}
indexColumn = 0;
indexRow++;
// read next line only at end of loop, not beginning of loop
// line is ready to be processed at next iteration
try {
line = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.print(Arrays.deepToString(table));
return table;
}
Arrays.deepToString is wrong. You are passing in an array of primitives. When you pass it in, you pass in double[][]. This is interpeted as Object[] where the objects are double[], so it will try to print double[] objects, and not print doubles.
One solution is to create an array Double[][].
Change
double[][] table = new double[4][10];
to
Double[][] table = new Double[4][10];
Autoboxing will convert each double to a Double. Since Double is an object and not a primitive, deepToString will print out each Double individually. If you read the javadoc for deepToString it explains that it operates recursively on arrays of reference type, not on primitive arrays.
If you want to stick with double[][]
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
System.out.print(table[i][j]);
System.out.print(' ');
}
System.out.println();
}
i have n cols and m rows in a specific file how i can but each col in a different array ?
*the number of rows and cols are changeable
String readline = null;
readline = read.readLine();
String[] getlength = readline.split(" ");
cols = getlength.length;
while (readline != null) {
readline = read.readLine();
rows++;
}
// Array of data
int[][] data = new int[rows][cols];
// New bufferedReader to put the cursor on the top of the file
read = new BufferedReader(new FileReader("1.txt"));
// for loop to skip first three rows
for (int i = 1; i <= 3; i++) {
read.readLine();
}
// to set the file Data into the array
String line = null;
line = read.readLine();
do {
readData = line.split(" ");
for (int j = 0; j < readData.length; j++) {
data[indexx][j] = Integer.parseInt(readData[j]);
}
indexx++;
line = read.readLine();
} while (line != null);
If you don't know the number of columns in the table you are reading you should use an ArrayList. One possible way would be:
[...]
ArrayList result = new ArrayList<int[]>();
line = read.readLine();
do {
readData = line.split(" ");
int[] row = new int[readData.length];
for(int i = 0; i < readData.length; i++) {
row[i] = Integer.parseInt(readData[i]);
}
result.add(row);
} while (line != null);
Now if you need your result as an array you can do the following conversion:
int[] data = result.toArray(new int[result.size()]);
I have a class Student and two children classes, CasualStudent and PermanentStudent. I am doing this right now.
Employee[] a = new Employee[10];
int count;
a[0] = new PermanentStudent("John", "LUI", "HJFDDFDFJ");
a[1] = new PermanentStudent("Peter", "VAMPLEW", "VAM12345678");
a[2] = new PermanentStudent("Rudi", "SKACEL", "SKA51515151");
a[3] = new CasualStudent("Katie","BLACKBURN","BLA41925612");
a[4] = new CasualStudent("Neal","STEPHENSON","STE97527467");
a[5] = new CasualStudent("Neneh","CHERRY","CHE98765432");
a[6] = new CasualStudent("Chris","BROOKMYRE","BRO97635198");
a[7] = new CasualStudent("Grace","HOPPER","HOP26554432");
a[8] = new CasualStudent("Randall","MUNROE","XKCD1234567");
a[9] = new CasualStudent("Kaylee","FRYE","FRY90224718");
Each of these children classes have a constructor and I have manually coded the data in the code. Now, I want to read this data from a .txt file. I know how to read and I have done this till now:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Program {
public static void main(String[] args) {
BufferedReader reader = new BufferedReader(new FileReader(
"file.txt"));
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
System.out.println(line);
}
reader.close();
}
}
But how do I read the data into the classes like this? I am new to Java and I am not able to understand how to do this? Please guide me in the right direction. Thanks!
Also, the text file will always contain 10 lines and each line will have the following format.
John LUI HJFDDFDFJ
..................
Code:
61. int i = 0;
62. for (i = 0; i < 10; i++)
63. {
64. String x = a[i].toString();
65. System.out.println(x);
66. }
The simplest way would be as follows:
Employee[] employees = new Employee[10];
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
for (int i = 0; i < 3; i++) {
String line = reader.readLine();
String[] parts = line.split(" ");
employees[i] = new PermanentStudent(parts[0], parts[1], parts[2])
}
for (int i = 3; i < 10; i++) {
String line = reader.readLine();
String[] parts = line.split(" ");
employees[i] = new CasualStudent(parts[0], parts[1], parts[2])
}
}
I am trying to make this input.txt into a 2D array. I tried a few different methods. This is my latest attempt, and I seem to be stuck here... Any help is much appreciated.
input.txt structure: SCI2000/Science/1200/10/C --> There are 23 rows and 5 columns. I'd also like to have a title made for each column.
FileReader fr = new FileReader("input.txt");
BufferedReader br = new BufferedReader(fr);
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
String[][] input = new String[23][5];
String[] tokens = everything.split("/");
for(String str : tokens)
System.out.print(str);
Just the main processing part (not tested):
int columns = 5;
String[] row = String[columns];
int j = 0;
while ((line = br.readline) != null) {
row = line.split("/");
for(int i=0; i<row.length; ++i) {
input[j,i] = row(i);
}
++j;
}
FileReader fr = new FileReader("input.txt");
BufferedReader br = new BufferedReader(fr);
String[][] input = new String[24][5]; // 1 row for title, 23 rows for data
// add title
input[0] = new String[]{"title1", "title1", "title1", "title1", "title1"};
String line = br.readLine();
int row = 1; // update here
while ( (line = br.readLine())!= null ) {
input[row++] = line.split("/");
}
// print all data
for ( int i = 0; i < input.length; i++) {
for ( int j = 0; j < input[i].length; j++ )
System.out.print(input[i][j] + " ");
//new line
System.out.println();
}