Storing a single csv object into an array - java

hey ive got a chunk of code thats supposed loads lines of csv file into an array of objects:
public static WarehouseItem[] loadRecords(WarehouseItem[] records) {
FileInputStream fileStrm = null;
InputStreamReader rdr;
BufferedReader bufRdr;
int numRows = 0;
String warehouseItem;
String filename;
filename = ConsoleInput.readLine("Please enter the filename (DataMillion.csv OR DataThousand.csv)");
try {
fileStrm = new FileInputStream(filename);
rdr = new InputStreamReader(fileStrm);
bufRdr = new BufferedReader(rdr);
warehouseItem = bufRdr.readLine();
records[numRows] = new WarehouseItem(warehouseItem); //NULL POINTER EXCEPTION HERE
System.out.println(records[0].toString(records[0].columnVals));
while (warehouseItem != null) {
numRows++;
records[numRows] = new WarehouseItem(warehouseItem);
warehouseItem = bufRdr.readLine();
}
fileStrm.close();
}
catch (IOException e) {
if (fileStrm != null) {
try {
fileStrm.close();
} catch (IOException ex2) {}
}
System.out.println("Error in file processing: " + e.getMessage());
}
main(null);
return records;
}
but when i run it, i get a NullPointerException on the line
records[numRows] = new WarehouseItem(warehouseItem);
is there anything that i missed??
heres the WarehouseItem constructor + toString:
public class WarehouseItem {
String[] columnVals;
int numColumns = 5;
public WarehouseItem(String warehouseItem) {
String key, brand, model, price, weightInKG;
int intWeightInKG;
double doublePrice;
StringTokenizer strTok;
strTok = new StringTokenizer(warehouseItem, ",");
key = strTok.nextToken();
brand = strTok.nextToken();
model = strTok.nextToken();
intWeightInKG = Integer.parseInt(strTok.nextToken());
doublePrice = Double.valueOf(strTok.nextToken());
weightInKG = String.valueOf(intWeightInKG);
price = String.valueOf(doublePrice);
String[] columnVals = {key, brand, model, weightInKG, price};
if(columnVals.length != 5)
throw new IllegalStateException("Invalid CSV: not enough columns");
}
public String toString(String[] columnVals) {
return ("Key: " + columnVals[0] + "\n" +
"Brand: " + columnVals[1] + "\n" +
"Model: " + columnVals[2] + "\n" +
"Weight: " + columnVals[3] + "\n" + " kg" +
"Price: " + "$" + columnVals[4] + "\n");
}
}
What my problem is the values aren't getting stored into the array records properly and im not sure why

You didn't initialize array, that was a cause NullPointerException in your code, but if you can't use array don't use it.
The number of lines might exceed the capacity of array, use List instead
List<WarehouseItem> records = new ArrayList<>();
String line = bufRdr.readLine();
while (line != null) {
WarehauseItem warehauseItem = new WarehauseItem();
records.add(warehauseItem);
warehauseItem.processLine(line);
line = bufRdr.readLine();
}
numRows = records.size();

When you create an array of objects in Java, it is initialized with all nulls. That is why you get a nullpointerexception.
So you need to create an object for each array position. In fact instead of calling a method you could just make that method a constructor; that would be simpler.
I also noticed another mistake: the method sets local variables, which only exist for the lifetime of the method, when in fact it should set instance variables.
Then I noticed a third mistake: You just caught exception, and assumed that that indicated missing columns; in fact it could indicate invalidly-typed data inside a column (e.g. string instead of integer).

You missed object creation records[numRows]=new WarehouseItem();
Your code need to be like this.
while (warehouseItem != null) {
records[numRows]=new WarehouseItem(); //here you forgot the object creation.
warehouseItem = bufRdr.readLine();
records[numRows].processLine(warehouseItem);
numRows++;
}

Because you haven't assigned anything to records[numRows]. You only defined records as an array of WarehouseItem objects.
You should assign a new WarehouseItem to that index of the array before you can use.
records[numRows] = new WarehouseItem();
warehouseItem = bufRdr.readLine();
records[numRows].processLine(wareHouseitem);

Related

Printing out array data stored from File read

I'm trying to create a class that uses a separate method to read and store two sets of data from a file into 2 different arrays. I don't know if it's the read method or my output that is incorrect but I can't seem to figure out how to have it printout all data sets. I get the last line of the file instead of all content.
examples from products.txt are
Product1,1100
Product2,1205
Product3,1000
Main Method
String[] pName;
double[] pPrice;
String outputStr = null;
int i = 0;
//String name = null;
// Input number of customers
//initialize arrays with size
pPrice=new double[50];
pName=new String[50];
// read from file, the method is incomplete
try {
readFromFile(pName, pPrice, "products.txt");
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "File cannot be read");
e.printStackTrace();
}
for (i = 0; i < pName.length; i++) {
outputStr = pName[i] + "," + pPrice[i] + "\n";
}
// Call method before sorting both arrays
display(outputStr);
Reading Method
public static void readFromFile(String[] pName, double[] pPrice, String fileName) throws FileNotFoundException {
// read data from products
// Create a File instance
File file = new File(fileName);
// Create a Scanner for the file
Scanner sc = new Scanner(file);
// Read data from a file, the data fields are separated by ','
// Change the Scanner default delimiter to ','
sc.useDelimiter(",|\r\n");
// Start reading data from file using while loop
int i = 0;
while (sc.hasNext()) {
String name = sc.next();
String cost = sc.next();
//add the customer data through arrays
pName[i] = name;
pPrice[i] = Double.parseDouble(cost);
i++;
}//end while
// Close the file
The problem is that your for loop assigns every line to the outputStr variable:
for (i = 0; i < pName.length; i++) {
outputStr = pName[i] + "," + pPrice[i] + "\n";
}
Seeing your linefeed in the end I assume you want to concatenate all lines into that string variable. So change that code into
for (i = 0; i < pName.length; i++) {
outputStr += pName[i] + "," + pPrice[i] + "\n";
}
As you initialize the variable to be null this may throw a NullPointerException. If that is the case, simply initialize with "".

write to separate columns in csv

I am trying to write 2 different arrays to a csv. The first one I want in the first column, and second array in the second column, like so:
array1val1 array2val1
array1val2 array2val2
I am using the following code:
String userHomeFolder2 = System.getProperty("user.home") + "/Desktop";
String csvFile = (userHomeFolder2 + "/" + fileName.getText() + ".csv");
FileWriter writer = new FileWriter(csvFile);
final String NEW_LINE_SEPARATOR = "\n";
FileWriter fileWriter;
CSVPrinter csvFilePrinter;
CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR);
fileWriter = new FileWriter(fileName.getText());
csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);
try (PrintWriter pw = new PrintWriter(csvFile)) {
pw.printf("%s\n", FILE_HEADER);
for(int z = 0; z < compSource.size(); z+=1) {
//below forces the result to get stored in below variable as a String type
String newStr=compSource.get(z);
String newStr2 = compSource2.get(z);
newStr.replaceAll(" ", "");
newStr2.replaceAll(" ", "");
String[] explode = newStr.split(",");
String[] explode2 = newStr2.split(",");
pw.printf("%s\n", explode, explode2);
}
}
catch (Exception e) {
System.out.println("Error in csvFileWriter");
e.printStackTrace();
} finally {
try {
fileWriter.flush();
fileWriter.close();
csvFilePrinter.close();
} catch (IOException e ) {
System.out.println("Error while flushing/closing");
}
}
However I am getting a strange output into the csv file:
[Ljava.lang.String;#17183ab4
I can run
pw.printf("%s\n", explode);
pw.printf("%s\n", explode2);
Instead of : pw.printf("%s\n", explode, explode2);
and it prints the actual strings but all in one same column.
Does anyone know how to solve this?
1.Your explode and explode2 are actually String Arrays. You are printing the arrays and not the values of it. So you get at the end the ADRESS of the array printed.
You should go through the arrays with a loop and print them out.
for(int i = 0; i<explode.length;++i) {
pw.printf("%s%s\n", explode[i], explode2[i]);
}
2.Also the method printf should be look something like
pw.printf("%s%s\n", explode, explode2);
because youre are printing two arguments, but in ("%s\n", explode, explode2) is only one printed.
Try it out and say if it worked
After these lines:
newStr.replaceAll(" ", "");
newStr2.replaceAll(" ", "");
String[] explode = newStr.split(",");
String[] explode2 = newStr2.split(",");
Use this code:
int maxLength = Math.max(explode.length, explode2.length);
for (int i = 0; i < maxLength; i++) {
String token1 = (i < explode.length) ? explode[i] : "";
String token2 = (i < explode2.length) ? explode2[i] : "";
pw.printf("%s %s\n", token1, token2);
}
This also cover the case that the arrays are of different length.
I have removed all unused variables and made some assumptions about content of compSource.
Moreover, don't forget String is immutable. If you just do "newStr.replaceAll(" ", "");", the replacement will be lost.
public class Tester {
#Test
public void test() throws IOException {
// I assumed compSource and compSource2 are like bellow
List<String> compSource = Arrays.asList("array1val1,array1val2");
List<String> compSource2 = Arrays.asList("array2val1,array2val2");
String userHomeFolder2 = System.getProperty("user.home") + "/Desktop";
String csvFile = (userHomeFolder2 + "/test.csv");
try (PrintWriter pw = new PrintWriter(csvFile)) {
pw.printf("%s\n", "val1,val2");
for (int z = 0; z < compSource.size(); z++) {
String newStr = compSource.get(z);
String newStr2 = compSource2.get(z);
// String is immutable --> store the result otherwise it will be lost
newStr = newStr.replaceAll(" ", "");
newStr2 = newStr2.replaceAll(" ", "");
String[] explode = newStr.split(",");
String[] explode2 = newStr2.split(",");
for (int k = 0; k < explode.length; k++) {
pw.println(explode[k] + "\t" + explode2[k]);
}
}
}
}
}

My array Printing NULL

In the method, i have all these initialize
Scanner input = new Scanner(System.in);
File file = new File("order.dat");
File viewOrder = new File("ViewOrder.dat");
String orderNo, itemNo, itemNameHolder, qtyHolder, priceHolder, status;
int hold, count = 0, countArray = 0;
double tempPriceHolder, totalPrice = 0;
String tempStatus = "";
String[] holdItemNo = null;
String[] holdName = null;
Integer[] holdQty = null;
Double[] holdTotal = null;
String[] holdStatus = null;
After, i try to read all my content in the file and store the content into holdX array
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
while ((line = br.readLine()) != null) {
String tokens[] = line.split(";");
orderNo = tokens[0];
itemNo = tokens[1];
itemNameHolder = tokens[2];
qtyHolder = tokens[3];
priceHolder = tokens[4];
status = tokens[5];
if (orderNo.equalsIgnoreCase(userOrderNo)) {
tempPriceHolder = Double.parseDouble(priceHolder);
hold = Integer.parseInt(qtyHolder);
tempPriceHolder = tempPriceHolder * hold;
totalPrice += tempPriceHolder;
countArray++;
holdItemNo = new String[countArray];
holdName = new String[countArray];
holdQty = new Integer[countArray];
holdTotal = new Double[countArray];
holdStatus = new String[countArray];
if (status.matches("s")) {
tempStatus = "Success";
} else if (status.matches("p")) {
tempStatus = "Partially Full";
} else if (status.matches("o")) {
tempStatus = "Out of Stock";
}
holdItemNo[count] = itemNo;
holdName[count] = itemNameHolder;
holdQty[count] = hold;
holdTotal[count] = tempPriceHolder;
holdStatus[count] = tempStatus;
count++;
}
}
} catch (Exception e) {
System.out.println("Error");
}
Final, i write all my array into a new file.
System.out.printf("%s %15s %15s %10s %10s\n", "Item No", "Description", "Quantity", "Total", "Status");
for (int i = 0; i < holdItemNo.length; i++) {
System.out.printf("\n%-11s %-18s %-13s $%-8s %s \n", holdItemNo[i], holdName[i], holdQty[i], holdTotal[i], holdStatus[i]);
}
System.out.println("-----------------------------------------------------------------------");
System.out.printf("%46s %s\n", "$", totalPrice);
System.out.print("Print Order to file Y/N: ");
String choice = input.next();
if (choice.equalsIgnoreCase("y")) {
try {
PrintWriter bw = new PrintWriter(new FileWriter("ViewOrder.dat", true));
for (int i = 0; i < holdItemNo.length; i++) {
bw.write(userOrderNo + ";" + holdItemNo[i] + ";" + holdName[i] + ";" + holdQty[i] + ";" + holdTotal[i] + ";" + holdStatus[i] + "\n");
bw.flush();
}
bw.flush();
bw.close();
System.out.println("Sucessfull!");
} catch (Exception e) {
System.out.println("Error");
}
} else if (choice.equalsIgnoreCase("n")) {
System.out.println("");
}
but the problem is even my code is working but the output is not what i expected. It printed out the printed out the last content and also the sub price is working as well but the rest is only printed out NULL.
Example
Also, it gave me warning of Derefencing possible null pointer on the array.length
for (int i = 0; i < holdItemNo.length; i++) {
bw.write(userOrderNo + ";" + holdItemNo[i] + ";" + holdName[i] + ";" + holdQty[i] + ";" + holdTotal[i] + ";" + holdStatus[i] + "\n");
bw.flush();
}
Guessing:
holdItemNo = new String[countArray];
and the following lines: you are creating these new array objects within your reading loop (inside a condition).
So probably that condition never goes true; therefore your arrays stay all null. But even when the condition is met - you probably expect that to happen more then once. And guess what: you are creating completely new arrays then. While throwing away the previously created array. Each time the if condition turns true you will lose previously stored values!
So the answer is: create your arrays before entering the loop. This means that you either have to query "how many slots to create" upfront; or you have to create an array with say 100 empty slots; and within your loop you then have to check if you still have free slots.
Or you start using java.util.List resp. ArrayList - which allows for dynamic adding of elements.

Java - NumberFormatException at linear search

I am having this issue with the NumberFormatException in my program. Basically, I am asked to read a .csv file separated by ; and it looks like this:
// Column Explanation (not in .csv file)
id; Summary; Number; Employee1; Employee2; ....... Employee7;
"1";"Sony";"1600";"Markos";"Nikos";"Antonis";"Nikolas";"Vaggelis";"Markos";"Thanasis";
"2";"HP";"1000";"Marios";"Dimitra";"Nikolia";"Spiros";"Thomas";"Kostas";"Manolis";
"3";"Dell";"1100";"Antonis";"Aggelos";"Baggelis";"Nikos";"Kuriakos";"Panagiotis";"Rafail";
"4";"Acer";"2000";"Marina";"Aggelos";"Spiros";"Marinos";"Xristos";"Antreas";"Basilis";
What I have already done is create a String 2-d array or the .csv file called temp_arr and I am asked to write a method that will run a linear search by id and return that company. So here is the thing.
At first, I thought I should convert the input key from int -> String since my temp_arr is a String and compares the strings (which at that time they would be int but read as Strings) using temp_arr[value][value2].equals(string_key). But I had a NullPointerException.
Then I thought I should better convert my Id's from the temp_arr from String -> Int and then compare with the integer key using == operand. This action returned me a NumberFormatException.
The process is this:
System.out.println("Enter id :");
Scanner input = new Scanner(System.in);
int item = input.nextInt(); // read the key which is an Integer
int id_int; // temp_arr is String and item is int, must convert ids from String -> int
for (int i = 0; i < temp_arr.length; i++)
{
id_int = Integer.parseInt(temp_arr[i][0]); // Convert from String to int
if (id_int == item) // If the Array's Id's are == item
{
System.out.println(item+" is present at location " + (i+1) );
break;
}
if (i == temp_arr.length)
System.out.println(item + " does not exist");
}
My error appears at line 7 and I do not know why.
Read File process:
String csvFile = "sam.csv"; // .csv file to be placed in the project file!
BufferedReader br = null; // ini
String line = "",cvsSplitBy = ";"; // columns asked to be split by ";"
String[] arr = null;
String[][] temp_arr = new String[1000][10];
int temp = 0;
try
{
br = new BufferedReader(new FileReader(csvFile)); //start reading the file
while ((line = br.readLine()) != null) // while the line has words
{
arr = line.split(cvsSplitBy); // creating the array
System.out.println(arr[0] + "\t" + arr[1] + "\t" + arr[2] + "\t" + arr[3] + "\t" + arr[4] + "\t" + arr[5] + "\t" + arr[6] + "\t" + arr[7] + "\t" + arr[8] + "\t" + arr[9] );
for (int i = 0; i<=9; i++)
{
temp_arr[temp][i] = arr[i]; // temp_arr represents (is a copy of) the .csv file
}
temp++;
}
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
if (br != null)
{
try
{
br.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
System.out.println("Done!\n");
Output (Image) :
Line 106 which is causing the issue is :
id_int = Integer.parseInt(temp_arr[i][0]); // Convert from String to int
Your issue is that your Integer.parseInt() is trying to parse a "2" WITH QUOTATION MARKS. That's the problem.
A quick solution would be to replace this line:
temp_arr[temp][i] = arr[i];
To this:
temp_arr[temp][i] = arr[i].replaceAll("\"", "");
Anyway, I'd like to suggest using a different data structure for your case, because I've done something like this before for a client. Have you ever heard of HashMaps? You can do something like a HashMap with an int key and String[] values to store your data in, and the key can be your id_int. Maybe you can try this implementation next time. It's a lot more elegant.
Hope I was able to help!
Cheers,
Justin
Would help if you also posted some of your data file and how you are reading it in.
But, my guess from what is presented is if you add System.out.println(temp_arr[i][0]) prior to the 7th line or run this code through a debugger you will see that temp_arr[i][0] is not an integer value as that is what the error is telling you.

Adding list to a list of lists doesn't work

I can not get this code to work.
The .txt file that it is reading from is here:
urls.txt
The problem with this code is that it does not at all add any lines.
Whenever i try to get anything at all from "lists" it gives me an IndexOutOfBoundsException.
The code gets executed each 30 seconds, so i have to call the lists.clear(); method.
NOTE: "lists" is defined earlier:
public static ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
This is my code:
try {
URL urls = new URL("https://dl.dropboxusercontent.com/u/22001728/server%20creator/urls.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(urls.openStream()));
lists.clear();
String line;
ArrayList<String> list = new ArrayList<String>();
lists.add(list);
int y = 0, z = 0;
while ((line = br.readLine()) != null) {
y++;
if(line.equalsIgnoreCase(">")) {
System.out.print("Received command: INSERT ");
lists.add(list);
list.clear();
z++;
System.out.print(" ; Jumping to " + z + "\n");
} else {
System.out.println("Line: " + line + " added to lists[" + z + "].");
lists.get(z).add(line);
}
}
int selectedIndex = comboModel0.getIndexOf(comboModel0.getSelectedItem());
comboModel0.removeAllElements();
System.out.println("\n\n\n");
System.out.println(lists.get(1).get(1));
System.out.println("\n\n\n");
} catch (IOException e) {
System.out.println("Failed to download URLS data.");
}
You are adding a list to your collection of lists, then clearing it. That will clear your local variable, plus the list in your collection.
lists.add(list);
list.clear();
You need to create a copy of that list to add to your collection.
lists.add(new ArrayList<String>(list));

Categories