How to read CSV data by matching the input in java? - java

Trying to create a program where the user is asked to enter a location, if the user enters i.e south it can read from the "Location" column in the csv, and whatever row contains "south" (upper or lowercase accepted), the name(s) from the Name column are printed. So if the user enters south, Holos and Deafer are returned.
I can't seem to find how to actually print specific rows that contains matching input, and have only been able to print the whole column.
Any help is much appreciated!
Csv
Name, Location
Holos, South
Tredies, North
Warren, West
Deafer, South
Current code that only reads specific column
public void filter() {
// using buffered reader to read the csv file, still a WIP
String path = "E:\\IT\\2022\\Further Programming\\s3902169_furtherProgrammingA1\\src\\files\\Melbnb.csv";
String line = "";
System.out.println("Enter location");
String stringInput = readUserInput();
BufferedReader br;
try {
br = new BufferedReader(new FileReader(path));
while ((line = br.readLine()) != null) {
String[] values = line.split(",");
if (stringInput.contains(values[1])) {
System.out.print(values[0]);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

if (stringInput.equalsIgnoreCase(values[1)) {
System.out.println(values[0]);
}

Related

Displaying data in JTable while reading the data from the text file

I'm trying to display the column data from separate file and row data from another but it's output is not in normal for row file below attached is the image file for output and both the text file:
private void orbuttonActionPerformed(java.awt.event.ActionEvent evt) {
DefaultTableModel model = (DefaultTableModel) orderitemtable.getModel();
model.setRowCount(0);
String filename = "ORDERITEMFILE.txt";
String idnamefile = "odcofile.txt";
File file1 = new File(idnamefile);
File file = new File(filename);
try {
BufferedReader br = new BufferedReader(new FileReader(file1));
BufferedReader br1 = new BufferedReader(new FileReader(file));
//to make the columns name so to get the first line of code
//set columnsname to the jtable Model
String firstLine = br.readLine().trim();
String[] columnsName = firstLine.split("/");
model.setColumnIdentifiers(columnsName);
//get lines from txt files
Object[] tablelines = br1.lines().toArray();
//Extracting the data from lines
//set data to jtable Model
for (int i = 0; i < tablelines.length; i++) {
String line = tablelines[i].toString().trim();
String[] dataRow = line.split(",");
model.addRow(dataRow);
}
} catch (Exception ex) {
Logger.getLogger(productpage.class.getName()).log(Level.SEVERE, null, ex);
}
}
The problem is its displaying the column's until product type after that it changes to new row and display the rest of content over there:
This is the text file for row it read's properly from the txt file the only problem is when it display in JTable it read's in separate row for the last two quantities.
This is the text file for column which.
First off, you really don't need a single file to hold Column Names. You can apply the Column Names as the very first line of your ORDERITEMFILE.txt file, very much like a CSV file would be laid out. Generally the first line of a CSV file would be a delimited string of the Column Names and it's there to be specifically used as such.
If you insist on utilizing two files then may I suggest you deal with the Column Names file first and be rid of it so that it doesn't clutter things up within your event code. Perhaps do this in a separate method:
private String[] getColumnNames(String filePath) {
String[] columns = {};
//Try with Resources (auto closes the reader)
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
// Assumes there is only one line in file.
while ((line = br.readLine()) != null) {
// Ignore blank lines (if any) leading to the line we want.
if (!line.equals("")) { break; }
}
if (line != null && !line.equals("")) {
columns = line.split("/");
}
}
catch (FileNotFoundException ex) {
System.err.println("Column Names File Not Found!");
}
catch (IOException ex) {
System.err.println("IO Exception Encounterd!\n" + ex.getMessage());
}
return columns;
}
Holding the thought of keeping things organized to some degree we now can have another method to set the new Column Names to JTable:
private void setTableColumns(JTable table, String[] columnsName) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setColumnIdentifiers(columnsName);
}
And still holding the organizational thought we have yet another method to fill the JTable with file data:
private int fillTableFromFile(JTable table, String filePath) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
int recordCount = 0;
//Try with Resources (auto closes the reader)
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
// Clear current table rows
while (model.getRowCount() > 0) {
for (int i = 0; i < model.getRowCount(); i++) {
model.removeRow(i);
}
}
String dataLine;
Object[] dataArray;
// read in the data and add to table.
while ((dataLine = br.readLine()) != null) {
// Ignore blank lines (if any).
if (dataLine.equals("")) { continue; }
//Split the comma delimited data line into a Object Array
dataArray = dataLine.split(",");
model.addRow(dataArray);
recordCount++;
}
}
catch (FileNotFoundException ex) {
System.err.println("Data File Not Found!");
}
catch (IOException ex) {
System.err.println("IO Exception Encounterd!\n" + ex.getMessage());
}
return recordCount; // The number of records added to table from file.
}
With the above methods in place you can now have some 'easy to follow' (and controllable) code within your JButton Action Performed event. By controllable, I mean for example, you can determine what is to happen if (for whatever reason) the coloumnsName String Array is empty or null (not handled here):
private void orbuttonActionPerformed(java.awt.event.ActionEvent evt) {
String filename="ORDERITEMFILE.txt";
String idnamefile="odcofile.txt";
String[] columnsName = getColumnNames(idnamefile);
setTableColumns(orderitemtable, columnsName);
int numOfRecords = fillTableFromFile(orderitemtable, filename);
JOptionPane.showMessageDialog(orderitemtable, "There were " + numOfRecords +
" Records Added to Table.", "Records Added",
JOptionPane.INFORMATION_MESSAGE);
}
When run and the Order Button is selected the table columns names will be placed, the table will be filled with file data, and a Message Box will appear indicating how many file records were added to table.

Java : How do I print an ascending column and next to that column the same set of integers except in descending order all in one single text file

I need some help in how to do a certain step as I can not seem to figure it out.
I was given a text file with 100 numbers in it all random, I am supposed to sort them either in ascending order, descending order, or both depending on the user input. Then which ever the user inputs the set of integers will be sorted and printed in a text file. I am having trouble printing the both file. Here is my code up until the both statement.
public static void print(ArrayList<Integer> output, String destination){
try {
PrintWriter print = new PrintWriter(destination);
for(int i = 0; i < output.size(); i++){
print.print(output.get(i) + " ");
}
print.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
BufferedReader br = null;
ArrayList<Integer> words = new ArrayList<>();
BufferedReader reader;
String numbers;
try {
reader = new BufferedReader(new FileReader("input.txt"));
while((numbers = reader.readLine()) != null)
{
words.add(Integer.parseInt(numbers));
}
System.out.println("How would you like to sort?");
System.out.println("Please enter asc(For Ascending), desc(For Decending), or both");
String answer = input.next();
Collections.sort(words);
if(answer.equals("asc")){
Collections.sort(words);
System.out.println(words);
print(words,"asc.txt");
}
else if(answer.equals("desc")){
Collections.reverse(words);
System.out.println(words);
print(words,"desc.txt");
When I type in "both" the text file that is created only has one column set of integers that is going in descending order, not both and I have no idea how to print both sets. If someone could shed some light I would really appreciate it.
else if(answer.equals("both")){
System.out.println(words);
print(words,"both.txt");
Collections.reverse(words);
System.out.println(words);
print(words,"both.txt");
You need to use FileOutputStreams#Constructor where you can pass a boolean value to tell whether to append to my file or not.
So use like this:
PrintWriter print = new PrintWriter(new FileOutputStream(destination, true));
/\
||
||
To append to the file
From JavaDocs
public FileOutputStream(File file,
boolean append)
throws FileNotFoundException
Parameters:
file - the file to be opened for writing.
append - if true, then bytes will be written to the end of the file
rather than the beginning

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.

Scanner only searching first line of .txt file

I'm in a beginning programming class, and seem to be having a major issue with searching a text file. What my code should do, based on the assignment:
Accept input, in this case a name and place that input into a .txt file
Allow the user to search for a name, or part of a name, and return all lines with matching text.
I have the input portion of the assignment complete, and am on the verge on completing the retrieval portion, but my code only searches the first line of the .txt file. I am able to print out all lines of the .txt file, and if I search for the name in Line 1 of the .txt file, it will print the line correctly. My issue comes when I am searching for a name that is not on Line 1. Below is my code:
System.out.println ("Would you like to retrieve names from your index? (YES/NO)");
try
{
retrieve=input.readLine();
}
catch (IOException E)
{
System.out.println(E);
}
}
if (choice == 2 && retrieve.equalsIgnoreCase("YES") || retrieve.equalsIgnoreCase("Y"))
{
while (retrieve2.equalsIgnoreCase("YES") || retrieve2.equalsIgnoreCase("Y"))
{
FileReader reader = new FileReader("Name_Index.txt");
BufferedReader bufferedReader = new BufferedReader(reader);
String line = bufferedReader.readLine();
System.out.println ("Enter a string of characters in which to search by or enter \"all names\" f$
search_term = gatherInput();
System.out.println("Search results include: ");
ArrayList<String> list = new ArrayList<String>();
Scanner inFile = new Scanner (new File("Name_Index.txt"));
inFile.useDelimiter(",");
while (inFile.hasNextLine())
{
list.add(inFile.nextLine());
}
Collections.sort(list);
if (search_term.equalsIgnoreCase("all names"))
{
for (String temp : list)
{
System.out.println(temp);
}
}
else if (line.toLowerCase().contains(search_term.toLowerCase()))
{
System.out.println(line);
bufferedReader.close();
}
System.out.println("End!");
System.out.println ("Would you like to retrieve names from your index? (YES/NO)");
try
{
retrieve2=input.readLine();
}
catch (IOException E)
{
System.out.println(E);
}
}
System.out.println("Thank you, come again!");
}
}
public static String gatherInput()
{
Scanner scan = new Scanner(System.in);
String user_input = scan.nextLine();
return user_input;
}
}
I have tried expanding the while (inFile.hasNextLine()) loop to include the second "if" statement, however that creates an issue for the "all names" search - it returns the entire list multiple times (however many lines are in the file). I have even tried creating another while (inFile.hasNextLine()) loop within the second "if" statement, and there is no difference in outcome.
I'm so frustrated at this point, because I've been working on this code for over a week, and have reviewed all of my notes and lecture recordings for this assignment with no help. Any insight would be much appreciated.
You are reading only 1 line of the file
String line = bufferedReader.readLine();
Why don't you read all lines and store them in a List;
List<String> lines = new ArrayList<>();
String line = bufferedReader.readLine();
while(line != null){
lines.add(line);
line = bufferedReader.readLine();
}
bufferedReader.close();
Then to print all lines containing a substring ignorecase:
lines.stream().filter(l -> l.toLowerCase().contains(search_term.toLowerCase))
.forEach(s -> System.out.println(s));
You need to loop the readLine()
For example:
File f = new File(ruta);
if(!f.exists()) //Error
else {
#SuppressWarnings("resource")
BufferedReader br = new BufferedReader(new FileReader(f));
String line;
while ((line = br.readLine()) != null) {
//line = the next line
}
}

Detect first line of text file separately?

I am designing a program that will load a text file into different media file classes (Media > Audio > mp3, Media > Video > Avi, etc).
Now the first line of my text file is how many files there are in total, as in
3
exmaple.mp3,fawg,gseges
test.gif,wfwa,rgeg
ayylmao.avi,awf,gesg
Now that is what is in my text file, I want to first get the first line separately, then loop through the rest of the files.
Now I understand I can simply count how many files are in by using an int that grows as I loop but I want it clear in the file aswell, and I'm not sure how to go about this.
static public Media[] importMedia(String fileName)
{
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line = reader.readLine();
while(line != null)
{
//Get the first line of the text file seperatly? (Then maybe remove it? idk)
//Split string, create a temp media file and add it to a list for the rest of the lines
}
//String[] split = s.next().split(",");
} catch (Exception ex) { System.out.println(ex.getMessage()); }
return null;
}
I hope my question is clear, if it TL;DR I want to get the first line of a text file separately, then the rest Id like to loop through.
I wouldn't advice using a for-loop here, since the file might contain additional lines (e.g. comments or blank lines) to make it more human-readable. By examining the content of each line, you can make your processing more robust against this sort of thing.
static public Media[] importMedia(String fileName)
{
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
// Get and process first line:
String line = reader.readLine(); // <-- Get the first line. You could consider reader as a queue (sort-of), where readLine() dequeues the first element in the reader queue.
int numberOfItems = Integer.valueOf(line); // <-- Create an int of that line.
// Do the rest:
while((line = reader.readLine()) != null) // <-- Each call to reader.readLine() will get the next line in the buffer, so the first time around this will give you the second line, etc. until there are no lines left to read.
{
// You will not get the header here, only the rest.
if(!line.isEmpty() || line.startsWith("#") {
// If the line is not empty and doesn't start with a comment character (I chose # here).
String[] split = line.split(",");
String fileName = split[0];
// etc...
}
}
} catch (Exception ex) { System.out.println(ex.getMessage()); }
return null;
}
You don't need while loop to read up to end of file. Read first line and convert it to int than loop through.
static public Media[] importMedia(String fileName)
{
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
// Get and process first line:
int lineNo=Integer.parseInt(reader.readLine());
// Now read upto lineNo
for(int i=0; i < lineNo; i++){
//Do what you need with other lines.
String[] values = reader.readLine().split(",");
}
} catch (Exception e) {
//Your exception handling goes here
}
}

Categories

Resources