BufferedReader returning columns instead of row - java

When I do this...
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
String[] data = line.split(",");
}
} catch (IOException e) {
e.printStackTrace();
}
If I print data[0], I get the first column instead of the first row. How can I modify it to return rows when I do data[0]?
When I did...
List<String> data;
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filename))) {
data = bufferedReader.lines().collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
And do data.get(0), I get rows as expected, so why not with the first method?

In your first example, you read each line with bufferedReader.readLine(), which already gives you a row. Then you split the row at the , char, which gives you columns for the current row.
Your seconds example, using bufferedReader.lines() returns a Stream of rows, which you collect with .collect(Collectors.toList()). Each of that rows in your List still simply has a string with all the commas in it. So what you probably want is a 2D-Array or a List<List<String>>.
You can achieve this as follows:
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
final List<List<String>> table = br.lines()
.map(row -> Stream.of(row.split(","))
.collect(Collectors.toList()))
.collect(Collectors.toList());
System.out.println(table.get(0));
} catch (IOException e) {
e.printStackTrace();
}

while ((line = bufferedReader.readLine()) != null) {
String[] data = line.split(",");
}
In here you're fetching a single line, spliting it into parts by , and assigning to the data variable. At that time you have a single line processed, there is no way to refer row x as you only got one row. And that variable is defined inside of the while loop so it's state is only accessible during one given iteration.

In a CSV file, each line is a row. Splitting the lines is what gives you the columns. So if you want the rows, you do not need to split the lines, just print them out the way they are. For example to print out just the first row, all you need to do is
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filename))) {
String firstRow = bufferedReader.readLine();
System.out.println(firstRow);
} catch (IOException e) {
e.printStackTrace();
}

Related

Java: Improving speed of a reader program

Hey so I am working on this program that reads CSV files and I need to make a method which can return one entire column on values.
Currently I do it like this:
List<String> data = new LinkedList<>();
for(int i = 0; i < getRowCount(); i++){
data.add(getRow(i).get(column));
}
Where getRow() is this:
List<String> data = new LinkedList<>();
String column;
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
for(int i = 0; i < row; i++){
bufferedReader.readLine();
}
column = bufferedReader.readLine();
for(String col: column.split(columnSeparator.toString())){
data.add(col);
}
} catch (IOException e) {
e.printStackTrace();
}
and it works. But the flaw is, if there are too many columns in a file it takes way too long. It takes 27 secondso n 7500 lines and 9 columns. Over 10 minutes on 35000 lines and 16 columns. Do you know how could I make it faster?
Try to read the file once:
List<String> getColumn(int column) {
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
List<String> data = new LinkedList<>();
String line = bufferedReader.readLine();
while (line != null) {
String cols[] = line.split(columnSeparator.toString());
data.add(cols[column]);
line = bufferedReader.readLine();
}
return data;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
What you are doing is the following:
Prepare to read the file (Creating ReaderObject, ...), read first line
Prepare to read the file, read first line, read second line
Preapre to read the file, read first line, read second line, read third line
.. And so on.
Apparently this is not very efficient (Your doing stuff in O(n²), with n = number of lines).
You could improve your code vastly, if you do it something like this:
Prepare to read the file
Read the first line
Read the second line
... And so on.
So first read all the lines at once:
List<String> lines = new LinkedList<>();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null)
lines.add(line);
} catch (IOException e) {
e.printStackTrace();
}
You can then iterate over the lines to split them into columns and extract the data you're interested in:
List<String> data = new LinkedList<>();
for(String line : lines)
data.add(line.split(columnSeparator.toString())[column]);
Of course this still needs a little bit of error handling :)
I would suggest you to try this
DataType<T> listRef = getRowCount();
for(int i = 0; i < listRef.size(); i++)
{
data.add(getRow(i).get(column));
}
getRowCount is executed every single time when you call it in a for statement and you would eventually get all the rows but internally I believe that calling makes it go and execute that method getRowCount().size() times and you probably don't want to read a file that many times

How can I read a specifc column from a text file and calculate the average of this column?

I am a little stuck with a java exercise I am currently working on. I have a text file in this format:
Quio Kla,2221,3.6
Wow Pow,3332,9.3
Zou Tou,5556,9.7
Flo Po,8766,8.1
Andy Candy,3339,6.8
I now want to calculate the average of the whole third column, but I have to extract the data first I believe and store it in an array. I was able to read all the data with a buffered reader and print out the entire file in console, but that did not get me closer to get it into an array. Any suggestions on how I can read in a specific column of a text file with a buffered readder into an array would be highly appreciated.
Thank you very much in advance.
You can split your text file by using this portion of code:
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("textfile.txt"));
String read = null;
while ((read = in.readLine()) != null) {
String[] splited = read.split(",");
for (String part : splited) {
System.out.println(part);
}
}
} catch (IOException e) {
System.out.println("There was a problem: " + e);
e.printStackTrace();
} finally {
try {
in.close();
} catch (Exception e) {
}
}
And then you'll have all your columns in the array part.
It`s definitely not the best solution, but should be sufficient for you
BufferedReader input = new BufferedReader(new FileReader("/file"));
int numOfColumn = 2;
String line = "";
ArrayList<Integer>lines = new ArrayList<>();
while ((line = input.readLine()) != null) {
lines.add(Integer.valueOf(line.split(",")[numOfColumn-1]));
}
long sum =0L;
for(int j:lines){
sum+=j;
}
int avg = (int)sum/lines.size();
I'm going to assume each data set is separated by newline characters in your text file.
ArrayList<Double> thirdColumn = new ArrayList<>();
BufferedReader in = null;
String line=null;
//initialize your reader here
while ((line = in.readLine())!=null){
String[] split = line.split(",");
if (split.length>2)
thirdColumn.add(Double.parseDouble(split[2]));
}
By the end of the while loop, you should have the thirdColumn ArrayList ready and populated with the required data.
The assumption is made that your data set has the following standard format.
String,Integer,Double
So naturally a split by a comma should give a String array of length 3, Where the String at index 2 contains your third column data.

Reading textfile line by line and put in object array

I have to make an EPG app using java, but I am kind of new in programming and it's due tomorrow and it's still not working properly.
I have a question about a small part: I have to read the programs from a text file. Each line contains multiple things, the channel, the title of the program, a subtitle, a category, etcetera.
I have to make sure that I can read the separate parts of each line, but it's not really working, it's only printing the parts from the first line.
I am trying, but I can't find why it's not printing all the parts from all the lines in stead of printing only the parts from the first line. Here's the code:
BufferedReader reader = new BufferedReader(newFileReader(filepath));
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
}
String[] parts = line.split("\\|", -1);
for(int i = 0; i < parts.length; i++) {
System.out.println(parts[i]);
}
reader.close();
Does anybody know how to get all the lines in stead of only the first?
Thank you!
readLine() only reads one line, so you need to loop it, as you said.
BUT with reading to the String inside of the while loop you always overwrite that String.
You would need to declare the String above the while loop that you can access it from outside, too.
BTW, it seems that your braces for the if don't match.
Anyway, I'd fill the information into an ArrayList, look below:
List<String> list = new ArrayList<>();
String content;
// readLine() and close() may throw errors, so they require you to catch it…
try {
while ((content = reader.readLine()) != null) {
list.add(content);
}
reader.close();
} catch (IOException e) {
// This just prints the error log to the console if something goes wrong
e.printStackTrace();
}
// Now proceed with your list, e.g. retrieve first item and split
String[] parts = list.get(0).split("\\|", -1);
// You can simplify the for loop like this,
// you call this for each:
for (String s : parts) {
System.out.println(s);
}
Use apache commons lib
File file = new File("test.txt");
List<String> lines = FileUtils.readLines(file);
As ArrayList is Dynamic,try,
private static List<String> readFile(String filepath) {
String line = null;
List<String> list = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader(filepath));
while((line = reader.readLine()) != null){
list.add(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}

Keep quotes when parsing csv

I know there is already a question related to this: How to keep quotes when parsing csv file? (But it's for C#)
Let's say I have a csv with values e.g:
12312414-DEF_234, "34-DE, 234-EG, 36354-EJ", 23
...
When I parse it with OpenCSV, it doesn't keep the quotes.
CSVReader reader = new CSVReader(new FileReader("../path.csv"), ',', '\"');
List<String[]> list = reader.readAll();
String[][] csvArray = new String[list.size()][];
csvArray = list.toArray(csvArray);
So, after I store all of the values into an array, when I try to print out the values (for checking), the quotes are not there.
...
System.out.println(csvArray[i][j]);
// output below
// 34-DE, 234-EG, 36354-EJ
How can I keep the quotes? The reason is because I am going to be changing some values, and need to re-output it back into a csv.
The CSVReader has to parse and remove the quotes, otherwise you wouldn't get one value 34-DE, 234-EG, 36354-EJ, but three values "34-DE, 234-EG and 36354-EJ". So it's OK that the quotes are being removed.
The CSVWriter should add them again for every value that needs quoting.
Have you tried to write the array back into a CSV? The value 34-DE, 234-EG, 36354-EJ - actually any value that contains a comma - should be quoted.
public static void readCSV(){
String csvFile = "input.csv";
BufferedReader br = null;
String line = "";
String splitter = ",";
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] words = line.split(splitter);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Reading Line in a random way, then print numbers in random order

Below is the text file, in which I want to read each line in some random way by printing each number in the line in some random order. I can read each line one by one and then print number corresponding to each line in a sequential order, But is there any way we can read line in some random way so that I can print all the numbers in some random order.
Line1 1 1116 2090 100234 145106 76523
Line2 1 10107 1008 10187
Line3 1 10107 10908 1109
Any suggestions will be appreciated. Below is the code that I wrote it will read the line sequentially.
BufferedReader br = null;
try {
String sCurrentLine;
br = new BufferedReader(new FileReader("C:\\testing\\Test.txt"));
while ((sCurrentLine = br.readLine()) != null) {
String[] s = sCurrentLine.split("\\s+");
for (String split : s) {
if(split.matches("\\d*"))
System.out.println(split);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
You can't "read a line in some random way" (well, you could, but it would be horrid!)
I'd suggest reading all your lines sequentially into a collection and then pick them out 1 at a time (randomly) until the collection is empty.
You can process each line individually in a similar way: parse all the numbers into a collection then pull them back out randomly.
e.g. (pseudo code)
ArrayList lines = new ArrayList()
while (! EOF)
lines.append(readLine)
while(lines.size() > 0)
int index = Random(0, lines.size)
line = lines[index];
lines.remove(index)
processLine(line)
// processLine does a similar thing to the above but with numbers
// on a line rather than lines in a file.
If you mean to rearrange the order of each line, you can use Collections.shuffle:
while ((sCurrentLine = br.readLine()) != null) {
List<String> s = Arrays.asList(sCurrentLine.split("\\s+"));
Collections.shuffle(s);
for (String split : s) {
if (split.matches("\\d*")) {
System.out.println(split);
}
}
}
This will print the lines sequentially, but the numbers in each line will be shuffled.
If mean to shuffle the order of the lines as well, just add each line to an ArrayList<List<String>>, shuffle the ArrayList, then shuffle each line:
ArrayList<List<String>> allLines = new ArrayList<List<String>>();
while ((sCurrentLine = br.readLine()) != null) {
allLines.add(Arrays.asList(sCurrentLine.split("\\s+")));
Collections.shuffle(allLines);
for (List<String> s : allLines) {
Collections.shuffle(s);
for (String split : s) {
if(split.matches("\\d*"))
System.out.println(split);
}
}
}
store your spilt variable into some arraylist or array of the type you want to have a collection of the numbers in your text file

Categories

Resources