I am writing some Java code to read each line of a data file into an array list, shuffle that list, and then perform some further operations on the shuffled data. The problem is that, after shuffling, I am getting null elements for some of the elements in the array list.
//this file contains the data
String input = ...;
//this file contains the number of rows in the data file
String input2 = ...;
FileInputStream fstream2 = new FileInputStream(input2);
DataInputStream in2 = new DataInputStream(fstream2);
BufferedReader brIndex = new BufferedReader(new InputStreamReader(in2));
for(int i = 1; i <= N; i++) {
FileInputStream fstream = new FileInputStream(input+(i+1)+".txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader brData = new BufferedReader(new InputStreamReader(in));
num = Integer.parseInt(brIndex.readLine());
ArrayList<String> temp = new ArrayList<String>();
for(int j = 0; j < num; j++) {
temp.add(brData.readLine());
}
brData.close();
Collections.shuffle(temp);
//read in shuffled data
for(int j = 0; j < num; j++) {
rowData = temp.get(j); ...
}
In executing the code, I get a NullPointerException after this when working with rowData. The original file has 17,169 rows (none of them are null). temp.size() is also 17,169 but when I printed temp out to the console, temp.get(j) was null for some j and not for others.
Can anyone explain to me why this is the case and how to avoid it?
The problem might be there are not enough lines in the file as num.
Try:
List<String> temp = new ArrayList<String>();
String line;
while((line = br.readLine()) != null) {
temp.add(brData.readLine());
}
You could also check for null elements in the list before you actually shuffle the list, as shuffle does not insert any new element to the list.
You never check if readLine() returns null or not. Check it, and you'll discover that you probably read past the end of the file.
Also, readers, writers and streams should always be closed in a finally block.
Related
I'm trying to read a text file and put each comma separated value in an array and put all of them inside a 2d array.But the code I have right now puts the whole line in the array
Scanner sc = new Scanner(new BufferedReader(new FileReader(path)));
int rows = 3;
int columns = 1;
String[][] myArray = new String[rows][columns];
while (sc.hasNextLine()) {
for (int i = 0; i < myArray.length; i++) {
String[] line = sc.nextLine().trim().split(" " + ",");
for (int j = 0; j < line.length; j++) {
myArray[i][j] = line[j];
}
}
}
System.out.println(Arrays.deepToString(myArray));
This is the text file:
A6,A7
F2,F3
F6,G6
Output
[[A6,A7], [F2,F3], [F6,G6]]
Expected Output
[[A6],[A7],[F2],[F3],[F6],[G6]]
The problem is that you are assigning the entire 2D array instead of just each item.
Here are several alternatives.
Use Files.lines to stream the file.
splitting on a comma creates the 1D array of two elements for each line
flatMap that to stream each item.
that map that to an array of one item.
then just store them in a 2D array.
String[][] array = null;
try {
array = Files.lines(Path.of("f:/MyInfo.txt"))
.flatMap(line->Arrays.stream(line.split(","))
.map(item->new String[]{item}))
.toArray(String[][]::new);
} catch (IOException ioe) {
ioe.printStackTrace();
}
if (array != null) {
System.out.println(Arrays.deepToString(array));
}
prints
[[A6], [A7], [F2], [F3], [F6], [G6]]
Here is an approach similar to yours.
List<String[]> list = new ArrayList<>();
try {
Scanner scanner = new Scanner(new File("f:/MyInfo.txt"));
while (scanner.hasNextLine()) {
String[] arr = scanner.nextLine().split(",");
for (String item : arr) {
list.add(new String[]{item});
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
There is no deepToString for Lists so you either iterate it or convert to a 2D array.
String[][] ar = list.toArray(String[][]::new);
System.out.println(Arrays.deepToString(ar));
prints
[[A6], [A7], [F2], [F3], [F6], [G6]]
i think you have to double the rows size and for each line just put one element and increment the i++
The declaration of the result array is not correct.
Since you want the end result should look like this, [[A6],[A7],[F2],[F3],[F6],[G6]], it is a 2-dimensional array with one row and six columns.
Considering it, I have changed and simplified your code.
int rows = 3;
String[][] r = new String[1][rows * 2];
FileInputStream fstream = new FileInputStream("/path/to/the/file")
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
while((line = br.readLine()) != null) {
String[] current = line.split(",");
r[0][i++] = current[0];
r[0][i++] = current[1];
}
I'm new to OOP, but I'm trying to create my first bigger program.
I've read a txt-file and stored the values (doubles) into an array, I call it originalArray. The text has two columns and 20 lines. So when I want to print the values in the first column of the txt-file I simply write:
System.out.println(originalArray[0]);
OUTPUT: 1991.00
300.50
498.50 .... et cetera...
My problem is that i'd like to use a for-loop (or whatever) to create two new arrays, each consisting one column from the "original array".
I thought it would be as simple as using a for-loop, like this;
double [] newArray = new double [20];
for(int i = 0; i < originalArray.length; i++){
newArray[i] = originalArray[0] //if I want to fill it with the first
//columns data... the second would be newArray2[i] = originalArray[1]
}
But this fills the new array with ONE element from the column in the originalArray... So - I need help to figure of how to write the loop to fill the new arrays with all elements from one chosen column.
Very grateful for help!
Regards/ frustrated newbie
EDIT: This is how I read the txt file:
String file = "C:\\Users\\komena\\Desktop\\30th-sales.csv";
BufferedReader br = null;
String line = "";
String splitBy = ";";
originalArray = new double [20];
br = new BufferedReader(new FileReader(file));
br.readLine();//skip the first line to get rid of header…
while ((line = br.readLine()) != null) {
String[] readlineArray = line.split(splitBy);
for (int i = 0; i < readlineArray.length; i++) {
originalArray[i] = Double.parseDouble(readlineArray[i]);
}
Whole text (csv) file:
300.50;330.00
489.50;296.50
34.50;399.50
900.00;1890.00
2052.00;568.00
354.00;0.00
399.00;0.00
1299.50;0.00
426.00;259.00
29.50;2300.50
99.50;349.50
2500.50;0.00
358.50;113.00
789.00;239.50
998.00;348.00
16.50;679.00
800.00;723.00
1899.50;950.50
550.50;568.00
Create the new 2D array with the size of the 1st dimension the same as the originalArray's length and the 2nd dimension the size of 2 (2 columns). Then simply loop it and add the old values to one column and also the new ones if reuqired, otherwise they will be set as 0.0 defaultly.
double originalArray[] = {1991.00, 300.50, 498.50};
double newArray[][] = new double[originalArray.length][2];
for (int i=0; i<originalArray.length; i++) {
newArray[i][0] = i // Fill the 1st column with sth like ID
newArray[i][1] = originalArray[i]; // Copy the 1D array to the 2nd column
}
System.out.println(Arrays.deepToString(newArray)); // Print all the array values
Output:
[[1.0, 1991.00],
[2.0, 300.50],
[3.0, 498.50]]
Moreover you read the file wrong. Notice that you have 2 values in the each line separated with ; and lines separated with \n. So read the line by line and add 2 values to the array.
The i variable represents the actual index of the originalArray[].
BufferedReader br = null;
String line = "";
int i=0;
double originalArray[] = new double[20];
br = new BufferedReader(new FileReader(file));
br.readLine();//skip the first line to get rid of header…
while ((line = br.readLine()) != null && i<originalArray.length) {
String[] readlineArray = line.split(";");
originalArray[i] = Double.parseDouble(readlineArray[0]);
originalArray[i+1] = Double.parseDouble(readlineArray[1]);
i+=2;
}
System.out.println(Arrays.toString(originalArray));
I want to read a .txt file via a Java program.
Say this is the text file input.txt
abc, test, 1,2,3
abc
abcd
test, 1, 2, 3
Each line represents a row, each comma-separated value represents a column.
Currently my code is:
BufferedReader br = new BufferedReader(new FileReader("input.txt"));
int num = readLines(); //this function just returns the number of lines
for (int i = 0; i < num; i++){
textData[i] = br.readLine();
}
br.close();
This outputs the text file as it was shown above if I print the array. But I require to insert into the array split by comma(could be other character as well, just use comma for now). So this means the output will be such that [abc,test,1,2,3],[abc],[abcd],[test,1,2,3] in the array. How should I proceed?
Thanks for the reply. Update:
Since i got my txt file into a array list,
[abc,test,1,2,3]
[abc]
[abcd]
[test,1,2,3]
How do i find the number of elements in each line?
Create an array list of array lists:
BufferedReader br = new BufferedReader(new FileReader("input.txt"));
int lineCount = readLines();
ArrayList<ArrayList<String>> rows = new ArrayList<ArrayList<String>>(lineCount);
for (int i = 0; i < lineCount; i++) {
ArrayList<String> row = new ArrayList<String>();
String line = br.readLine();
for(String s: line.split(",")) {
row.add(s);
}
rows.add(row);
}
br.close();
I have a file with lines of text like this:
[A]
This is one line.
This is another line.
[B]
A third line.
...
and so forth. I want to read this file into Java and look for the lines which only contain [A] etc. for further reference. I tried:
Resources res = getResources();
InputStream in_s = res.openRawResource(R.raw.texts);
byte[] b = new byte[in_s.available()];
in_s.read(b);
String textstring = new String(b);
String[] textarr = textstring.split("[\\r\\n]+");
And then:
int lineB = 0;
for (int i=0; i<textarr.length; i++) {
if textarr[i].substring(0, 3) == "[B]") lineB = i;
}
Afterwards, line is still zero. First I thought this has something to do with how new lines are handled (I'm using Windows), but I also had no luck with substring(0,3). I want this to give me lineB = 3, any ideas what I'm doing wrong?
Use String#startsWith like this:
int lineB = 0;
for (int i=0; i<textarr.length; i++) {
if (textarr[i].startsWith("[B]"))
lineB = i;
}
Try String.contains(CharSequence s) or String.startsWith(String prefix)
edit: Oh, and try BufferedReader:
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
String line = "";
while ((line = in.readLine()) != null)
if(line.startsWith("whatever")) ...
I want to read lines of numbers from a file. The code is as follows but the IDE shows NullPointerException runtime exception. Not sure what I am doing wrong.
//reading the contents of the file into an array
public static void readAndStoreNumbers() {
//initialising the new object
arr = new int[15][];
try {
//create file reader
File f = new File("E:\\Eclipse Projects\\triangle.txt");
BufferedReader br = new BufferedReader(new FileReader(f));
//read from file
String nums;
int index = 0;
while ((nums = br.readLine()) != null) {
String[] numbers = nums.split(" ");
//store the numbers into 'arr' after converting into integers
for (int i = 0; i < arr[index].length; i++) {
arr[index][i] = Integer.parseInt(numbers[i]);
}
index++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
Your second dimension of arr is uninitialized, and you are invoking
arr[index].length
You could be running into an NPEX for two reasons.
You don't finish your definition of arr - it's not evident in your code that you declare arr as int arr[][];
Even if you had the above, you wouldn't have set aside space for your second array. What you have now is a jagged array; you can have elements of whatever length in the second dimension you wish in your second array.
The only modification I made to your code to get it to work would be the following line:
arr[index] = new int[numbers.length];
...after pulling elements into numbers, and before entering the loop.
you need to change -
for(int i=0; i<arr[index].length; i++) {
to
arr[index] = new int[numbers.length];
for (int i = 0; i < numbers.length; i++) {
Java doesn't have real multidimensional arrays. What you are using is actually an array of int arrays: new int[n][] actually creates an array with room for n objects of type int[].
Consequently you will have to initialize each of those int arrays separately. That would have been obvious from the fact that you never actually specified the length of the second dimension anywhere in your program.
I think you should use StringBuilder..
//reading the contents of the file into an array
public static void readAndStoreNumbers() {
//initialising the StringBuffer
StringBuilder sb = new StringBuilder();
try {
//create file reader
File f = new File("E:\\Eclipse Projects\\triangle.txt");
BufferedReader br = new BufferedReader(new FileReader(f));
//read from file
String nums;
int index = 0;
while ((nums = br.readLine()) != null) {
String[] numbers = nums.split(" ");
//store the numbers into 'arr' after converting into integers
for (int i = 0; i < arr[index].length; i++) {
sb.append(Integer.parseInt(numbers[i])).append("\n");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}