Why last value in a csv keeps repeating itself when reading from - java

Here is a look at the function I have been messing with for a day now. For some reason it writes the last value in the csv over and over as opposed to parsing through the rows. I threw in some print statements and it appears the row contents are correctly writing to the array but are being over written by the last value. Any help would be amazing, thanks.
public int csvCombine(ArrayList <Indexstruct> todaysCSV, int totalconvo, String date) throws IOException{
String rows = null;
Indexstruct templist=new Indexstruct();
String [] rowArray= new String [2];
FileReader fr = new FileReader(date + ".csv");
BufferedReader br = new BufferedReader(fr);
rows= br.readLine();
rowArray=rows.split(",");
totalconvo+=Integer.parseInt(rowArray[0]); //Reads in total amount of words spoken and adds it to the CSV value of words spoken
final int csvSize=Integer.parseInt(rowArray[1]); //Read in size of csvList
for(int count=0; count<csvSize-1; count++){
rows = br.readLine();
rowArray = rows.split(","); // Reads lines into an array, takes array values and places them into an object of type indexStruct to write into ArrayList
templist.numOfUses=Integer.parseInt(rowArray[1]); //sets object num of uses
templist.Word=rowArray[0]; //sets object word
todaysCSV.add(count, templist); //adds object to csv ArrayList
}
br.close();
return totalconvo;
}

All you're currently doing is adding the same templist object over and over again, and so it makes sense that all data is the same. You need to create a new templist object (whatever type it is) with each iteration of the for loop.
i.e.,
for(int count=0; count < csvSize-1; count++) {
rows = br.readLine();
rowArray = rows.split(",");
int useCount = Integer.parseInt(rowArray[1]);
String word = rowArray[0];
// assuming a type called TempList with a constructor that looks like this
todaysCSV.add(count, new TempList(useCount, word));
}

Related

reading comma separated text files of different lengths in java

so I have a text file and i am trying to read line by line and then populate my array list.
a sample text file is shown below:
10,11,11/10/2021,24,1,2
11,12,11/10/2021,1,2,3
12,13,11/10/2021,24,5
13,14,11/10/2021,1,11,32,2
14,15,11/10/2021,1,9,8
I have been able to read in the first 4 elements (ID,ID,date,price)
and then i need to populate the other elements on that line into an array list (all elements after price)
the problem I am having is that it populates all the other lines into the array list and just not the remaining elements for the one line.
here is the code
int ID = 0;
int spareID = 0;
String date = "";
float fee = 0;
ArrayList<String> limits = new ArrayList<String>();
ArrayList<Import> imports= new ArrayList<Imports>();
File myfile = new File("file.txt");
try {
Scanner inputFile = new Scanner(myfile);
inputFile.useDelimiter(",");
// setting comma as delimiter pattern
while (inputFile.hasNextLine()) {
ID = inputFile.nextInt();
SpareID = inputFile.nextInt();
date = inputFile.next();
fee = inputFile.nextFloat();
while (inputFile.hasNext()) {
limits.add(inputFile.next());
}
Import import = new Import(ID, spareID, fee, date, limits);
imports.add(import);
}
inputFile.close();
} catch (FileNotFoundException e) {
System.out.println("error: can not find file");
}
the array list is capturing the rest of the text file when i need it to capture just the remaining elements on that line.
Edit: the first 4 elements of the line will all go into a different variable and then I need the rest or the elements on that line only to go into the array list
Use Scanner.nextLine() to get a single line, then create a second Scanner with that line to parse it contents.
Scanner inputFile = new Scanner(myfile);
while (inputFile.hasNextLine()) {
Scanner line = new Scanner(inputFile.nextLine());
// setting comma as delimiter pattern
line.useDelimiter(",");
ID = line.nextInt();
SpareID = line.nextInt();
date = line.next();
fee = line.nextFloat();
while (line.hasNext()) {
limits.add(line.next());
}
}
inputFile.close();

Breaking down textfile into Arraylist - Java

I am trying to break down a data text file which is in the format of:
kick, me, 10
kick, you, 20
into arrayList<customlist> = new arrayList
class customlist
{
string something, string something2, int times
}
So my question is how can I get each part of the text file data to each part of the customlist.
eg: kick -> something, me -> something2 and 10 -> times
Try to split each line into its components using String.split(",").
Apply String.trim() to each member in order to get rid of the spaces.
There are many way to solve this type of problem, here you can simply read all text from that text file by using InputStream and BufferReader after geting all text you can do somthing like:-
ArrayList<CustomList> getArrayList(String textFileData)
{
ArrayList<CustomList> customLists = new ArrayList<>() ;
String data[] = textFileData.split(",");
int i = data.length;
int position = 0;
while (position<i)
{
String somthing = data[position];
String somthing1 = data[position+1];
String temp = data[position+2].split(" ")[0];
int times = Integer.parseInt(temp);
CustomList customList= new CustomList();
customList.setSomething(somthing);
customList.setSomething2(somthing1);
customList.setTimes(times);
customLists.add(customList);
position = position+3;
}
return customLists;
}
Note: this is refer if you are using same string pattern as you mention in the above problem
Using a Scanner object to read the lines and breaking up each line using the split() function. Then, create a new customlist object, and add it into your ArrayList<customlist>.
public void readFile(File file, ArrayList<customlist> myList)
{
Scanner sc = new Scanner(file);
String line;
while(sc.hasNextLine())
{
line=sc.nextLine();
String[] fields = line.split(",");
int times = Integer.parseInt(fields[2].trim());
customlist myCustom = new myList(fields[0].trim(), fields[1].trim(),
times);
myList.add(myCustom);
}
sc.close();
}
You may also handle exceptions if you think its necessary.

Find a specific line in a file, write that line and the 2 after to a new file

I need to search for a specific line in a .txt file like someones name and then write the name and the next 2 lines after which is data about the person to a new file.
How it should work:
I enter a menu which lists employees taken from an arraylist and asks for my input for who I want a "report" for. I enter "John Doe" and the program creates a "report" called "JDoe.txt" and searches the arraylist for "John Doe" and writes his name in the new file along with his information (the next 2 lines after his name in the same file).
My code is creating the "report" and is writing data to it, but it just writing the data of what is first in the arraylist and not specifically the user who I entered. How do I write for the specific user I inputted?
Here is some of the code I have which is in the right direction but isn't producing what I want and I can't seem to figure out a fix:
import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Report { // FirstName LastName, Programmer
public Report() {
// code here the logic to create a report for the user
try {
String empList = "";
ArrayList<String> emps = new ArrayList<>();
String[] firstLine = new String[100], secondLine = new String[100], thirdLine = new String[100];
int index;
FileReader file = new FileReader("payroll.txt");
BufferedReader buffer = new BufferedReader(file);
String line;
for (index = 0; index < 100; index++) {
firstLine[index] = "";
secondLine[index] = "";
thirdLine[index] = "";
}
index = 0;
while ((line = buffer.readLine()) != null) {
firstLine[index] = line;
secondLine[index] = buffer.readLine();
thirdLine[index] = buffer.readLine();
emps.add(firstLine[index]);
index++;
}
buffer.close();
Collections.sort(emps);
for (String str : emps) {
empList += str + "\n";
}
String input = JOptionPane.showInputDialog(null, empList,
"Employee List", JOptionPane.PLAIN_MESSAGE);
index = 0;
// Iterate through the array containing names of employees
// Check if a match is found with the input got from the user.
// Break from the loop once you encounter the match.
// Your index will now point to the data of the matched name
if (emps.contains(input)) {
JOptionPane.showMessageDialog(null, "Report Generated.",
"Result", JOptionPane.PLAIN_MESSAGE);
String names[] = new String[2];
names = input.split(" ");
String fileName = names[0].charAt(0) + names[1] + ".txt";
// Create a FileWritter object with the filename variable as the
// name of the file.
// Write the necessary data into the text files from the arrays
// that
// hold the employee data.
// Since the index is already pointing to the matched name, it
// will
// also point to the data of the matched employee.
// Just use the index on the appropriate arrays.
File check1 = new File(fileName);
FileWriter file2;
if (check1.exists())
file2 = new FileWriter(fileName, true);
else
file2 = new FileWriter(fileName);
BufferedWriter buffer2 = new BufferedWriter(file2);
buffer2.write("Name: " + firstLine[index]);
buffer2.newLine();
buffer2.write("Hours: " + secondLine[index]);
buffer2.newLine();
buffer2.write("Wage: " + thirdLine[index]);
buffer2.newLine();
buffer2.close();
} else {
JOptionPane.showMessageDialog(null, input + " does not exist");
Report rpt = new Report();
}
} catch (IOException e) {
System.out.println(e);
}
}
public static void main(String[] args) {
new Report();
}
}
What the file it is reading from looks like:
There were two problems I found. The first was that after you when through and built your list of names, you were setting index = 0, and it never got changed.
for (String str : emps) {
empList += str + "\n";
}
//Make the JOptionPane...
index = 0;
This meant you were always getting the first value. If you set index to 1, you would get the second value. You can use the method indexOf(Object o) from the ArrayList library to get the correct index given the name that the user input. Example:
int i = emps.indexOf(input);
buffer2.write("Name: " + firstline[i]);
However, this would only partly solve the problem, as you sorted the list of employee names in emps, but not in the arrays you are using to write.
One solution to this is to not sort the emps array, which gives you the correct ordering to indexOf to work properly, but the employees listed in the JOptionPane will be listed in the order they were in the file.
However, since the values given for each employee are tied to that employee, I would suggest using a data structure that ties those values to the employee name, such as a Map. (Documentation is here: http://docs.oracle.com/javase/7/docs/api/java/util/Map.html ).
To initialize it, you can use it like this. I'm using a linkedHashMap because it came to my mind, you can select the proper type for your needs.
LinkedHashMap myMap<String, String[]> = new LinkedHashMap<String, String[]>();
The first field, String is your Key, which will be your employees name. The Value is the String[], and can be an array with the required two values. This ties these values to the name, ensuring they cannot get lost. To check for a name, just use myMap.containsKey(name), and compare to null to see if it exists, and then use myMap.get(name) to get the entry for that name.

Read a text file to an array Java

I know there are many questions about reading text files here but I have gone through all of them and I think I'm having some difficulty with syntax or SOMETHING because nothing that I've been trying has been working at all.
What I'm attempting to do is this:
1) read a text file inputed by user
2) copy each individual line into an array, so each line is its own element in the array
I feel like I am very close but for some reason I can't figure out exactly how to get it to work!
Here is the relevant code I have right now:
I keep getting out of bounds exceptions in three locations which I've marked off.
Been working on this for quite a while not sure what to do next! Any ideas?
import java.io.IOException;
import java.util.Scanner;
public class FindWords {
public static void main (String args[]) throws IOException{
FindWords d = new Dictionary();
((Dictionary) d).dictionary(); //********* out of bounds here
}
/**
* Validates and returns the dictionary inputed by the user.
*
* #param
* #return the location of the dictionary
*/
public static String getDict(){
///////////////////ASK FOR DICTIONARY////////////////////
System.out.println("Please input your dictionary file");
//initiate input scanner
Scanner in = new Scanner(System.in);
// input by user
String dictionary = in.nextLine();
System.out.println("Sys.print: " + dictionary);
//make sure there is a dictionary file
if (dictionary.length() == 0){
throw new IllegalArgumentException("You must enter a dictionary");
}
else return dictionary;
}
}
which calls on the class Dictionary:
import java.io.*;
public class Dictionary extends FindWords{
public void dictionary () throws IOException{
String dict = getDict();
String[] a = readFile(dict); //********** out of bounds here
int i = 0;
while(a[i] != null){
System.out.println(a[i]);
i++;
}
}
public static String[] readFile(String input) throws IOException{
//read file
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(input)));
System.out.println ();
int count = 0;
String[] array = new String[count];
try{
while (br.readLine() != null){
array[count] = br.readLine(); //********out of bounds here
count++;
}
br.close();
}
catch (IOException e){
}
return array;
}
}
Thank you for looking!
Edit: Just fyi: I have my .txt file in the parent project folder.
Have you tried this?:
List<String> lines = Files.readAllLines(Paths.get("/path/to/my/file.txt"));
and then transform your list to an array if you want:
String[] myLines = lines.toArray(new String[lines.size()]);
You start with an array size of zero...
int count = 0;
String[] array = new String[count];
Several issues here :
In Java, you can't expand arrays, i.e you have to know their length in advance when you instantiate them. Hence the ArrayOutOfBoundException. To make this easy, I suggest that you use an ArrayList instead.
In your while loop, you're making 2 calls to br.readLine(), so basically you're skipping one line out of 2.
You are initializing a zero-length array, hence the exception on the first iteration:
int count = 0;
String[] array = new String[count];
Since you probably don't know the expected size, work with a List instead:
List<String> list = new ArrayList<>();
String thisLine = null;
try{
while ((thisLine = br.readLine()) != null) {
list.add(thisLine);
}
}
You can get the total size afterwards by:
list.size();
Or even better, go with morganos solution and use Files.readAllLines().

How To Compare Values Between Two Different Sized Csv Files?

I was wondering what is the most appropriate way of looping through two csv files and comparing their columns. Specifically I want to compare the csv file1 1st column to every iteration of csv file2 column 20 and check to see if there is a match. Here is what i have so far. In addition csv file1 is considerably smaller than csv file2.
public class ClassifyData {
public static void main(String[]args) throws IOException{
File file1 = new File("file1.csv");
File file2 = new File("file2.csv");
FileWriter writer = new FileWriter("/Users/home/Work.csv");
PrintWriter pw = new PrintWriter(writer);
Scanner in = new Scanner(file1);
Scanner in2 = new Scanner(file2);
boolean firstLine = true;
String[] temp = null;
String [] temp2 = null;
String line = null;
String line2 = null;
while((line = in.nextLine())!=null){
temp= line.split(",");
while(line2 = in2.nextLine() !=null){
temp2 = line2.split(",");
if(temp[0] == temp[20]){
System.out.println("match");
pw.append("0");
continue;
}
pw.append("\n");
}
}
pw.flush();
pw.close();
writer.close();
}
}
In the line if(temp[0] == temp[20]) you probably mean if(temp[0].equals(temp2[20])). This will give you the comparison you want. However, you're inner while loop still won't start over at the beginning of the second file like you seem to want. I don't think Scanner objects can start over on a file, and even if they could, you'd be wasting a lot of file reads by reading the same file over and over. Something like this will be more efficient for your disk:
ArrayList<String> list1 = new ArrayList<String>;
while((line = in.nextLine())!=null){
temp= line.split(",");
list1.add(temp[0]);
}
// ...
for(int i = 0; i < list1.size(); i++){
for(int j = 0; j < list2.size(); j++){
if(list1.get(i).equals(list2.get(j))){
System.out.println("Match found");
}
}
}
Warning: untested code
I don't think your solution is going to work because you're going through both files just once (you're sequentially incrementing through both files simultaneously). Given that the first file is small, I suggest going through that file completely once, and store the values in the first column in a hashtable. Then cycle through the second file, and check if the value in the 20th column appears in the hashtable or not.

Categories