Read data from a text file and create an object - java

I need some help:
I'm making a Supermarket simulation on Java, but I've got one problem, I have a text file (Stock.txt) where I have all the supermarket stock on it for example:
0-Bakery-Chocolate Cake-$12.5-250
1-Meat-Premium Steak-$2.6-120
2-Seafood-Tuna - $1.2-14
...
Where the first number is the "id" for the product, next is the department the product belongs, third is the name of the product, the next thing is the price, and the last number is how much pieces of the product the stock has.
I have this class:
public class Product {
protected String name;
protected double price;
protected String department;
protected int id;
protected int stock;
}
So, basically what I need to do is to read each line from the text file and create the product, i.e. for the first line make something like this:
Product product1 = new Product(0,"Bakery","Chocolate Cake", 12.5, 250);
And then add it to an array
Product[0] = product1;
For all the things that are in the text file, then, when running the simulation each costumer will buy a random quantity of random products in stock, so the stock number will decrease. Finally, when the simulation ends, the program must write in the same text file, the modify quantity of each product.
The thing is that maybe it's too easy to do but I have no idea of how to do this, because reading and writing a file in Java has been a real problem for me since I started programming in Java (I'm a beginner).
I have some ideas of using the BufferedReader and the StringTokenizer classes for the reading and creating the object problems, but I can't figure it out how to do it, and I have no idea of how must I do the overwritting problem.
I'd really appreciate your help!
Oh! By the way, I really need to use only the arrays, so using an ArrayList or any other structure it's not even a choice :(

This is a good job for a Scanner to read in the data. As far as not being able to use collections like ArrayList you'll have to dynamically reallocate an array yourself.
Try the following:
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("Stock.txt"));
input.useDelimiter("-|\n");
Product[] products = new Product[0];
while(input.hasNext()) {
int id = input.nextInt();
String department = input.next();
String name = input.next();
double price = Double.valueOf(input.next().substring(1));
int stock = input.nextInt();
Product newProduct = new Product(name, price, department, id, stock);
products = addProduct(products, newProduct);
}
for (Product product : products) {
System.out.println(product);
}
}
private static Product[] addProduct(Product[] products, Product productToAdd) {
Product[] newProducts = new Product[products.length + 1];
System.arraycopy(products, 0, newProducts, 0, products.length);
newProducts[newProducts.length - 1] = productToAdd;
return newProducts;
}
public static class Product {
protected String name;
protected double price;
protected String department;
protected int id;
protected int stock;
private static NumberFormat formatter = new DecimalFormat("#0.00");
public Product(String n, double p, String d, int i, int s) {
name = n;
price = p;
department = d;
id = i;
stock = s;
}
#Override
public String toString() {
return String.format("ID: %d\r\nDepartment: %s\r\nName: %s\r\nPrice: %s\r\nStock: %d\r\n",
id, department, name, formatter.format(price), stock);
}
}
Results:
ID: 0
Department: Bakery
Name: Chocolate Cake
Price: 12.50
Stock: 250
ID: 1
Department: Meat
Name: Premium Steak
Price: 2.60
Stock: 120
ID: 2
Department: Seafood
Name: Tuna
Price: 1.20
Stock: 14

For simplicity, I have defined all the items as String.
Product DAO:
public class Product {
private String name;
private String price;
private String department;
private String id;
private String stock;
//generate `enter code here`
//getters & setters
//toString
Put your product list in "testData/product.txt". This is assuming that your list of products comes in same format, i.e. id-department-name-price-stock \n.
Use the jUnit test below to test your code. You can certainly modify how you read the product.txt file (may be other powerful string readers).
#Test
public void test() {
try {
List<String> productLines = Files.readAllLines(java.nio.file.Paths.get("./testData/product.txt"), StandardCharsets.UTF_8);
for (String line: productLines)
Product product = new Product();
String[] tokens = line.split("-");
product.setId(tokens[0]);
product.setDepartment(tokens[1]);
product.setName(tokens[2]);
product.setPrice(tokens[3]);
product.setStock(tokens[4]);
System.out.println(product.toString())
}
} catch (IOException e) {
e.printStackTrace();
}
}

For future readers.
I had double quotes surrounding my csv (comma separated values) file.
And had some doubles and ints.
I also has going nuts trying to find a "bad line" and the value that was barfing.... in the csv file. Thus my exception with a decent message.
My "delimiter" is a comma and carriage return. And I deal with the double quotes "at the column level".
Here is what I came up with.
/* I know, a java example with the imports listed out ! shocking !! */
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
private void loadFromFile() {
Collection<MyCustomObject> items = new ArrayList<MyCustomObject>();
int lineNumber = 0;
String nextValue = "";
try {
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("MyFile.txt").getFile());
Scanner input = new Scanner(file)
.useDelimiter(",|\\R")
.useLocale(Locale.ENGLISH);
;
/* skip the header */
input.nextLine();
while (input.hasNext()) {
lineNumber++;
nextValue = input.next().replace("\"", "");
String zipCodeValue =nextValue;
nextValue = input.next().replace("\"", "");
String city = nextValue;
nextValue = input.next().replace("\"", "");
String usaState = nextValue;
nextValue = input.next().replace("\"", "");
double latitude = Double.valueOf(nextValue);
nextValue = input.next().replace("\"", "");
double longitude = Double.valueOf(nextValue);
nextValue = input.next().replace("\"", "");
int population = Integer.valueOf(nextValue);
items.add(new MyCustomObject(zipCodeValue, city, usaState, latitude, longitude, population));
}
} catch (Exception ex) {
throw new RuntimeException(String.format("Line number '%s, nextValue '%s''", lineNumber, nextValue), ex);
}
}
Sample text (csv) file:
"ZIPCODE","CITY","STATE","LATITUDE","LONGITUDE","POPULATION"
"06778","NORTHFIELD","CT",41.707,-73.105,555
"06779","OAKVILLE","CT",41.595,-73.081,777
"06782","PLYMOUTH","CT",41.657,-73.041,888

Related

Creating objects from reading a file that also have dynamic arrays as their fields

I have a text file that contains purchase informations and it has a structure like this
CustomerName tab MembershipType tab ShoppingDate tab ProductName tab Quantity newline
A customer can purchase several different objects at once so ProductName and Quantity can occur more than one time like this
Mary gold 26.01.2020 Sweater 1 Jeans 2
Eve silver 20.02.2020 Sweater 2 Jeans 1
Steve bronze 19.01.2020 Jeans 2 Sweater 3
I am currently trying to create an customers object from these data here is my implementation
import java.io.File;
import java.io.FileNotFoundException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException, ParseException {
Scanner shoppingList = new Scanner(new File("shoppingList.txt");
shoppingList.useDelimiter("[\t\n]");
Customer[] customers = new Customer[0];
while (shoppingList.hasNext()) {
String customerName = shoppingList.next();
String customerMembershipType = shoppingList.next();
String purchaseDate = shoppingList.next();
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
Date date = formatter.parse(purchaseDate);
String[] productNameList = new String[0];
int[] quantityList = new int[0];
while (shoppingList.hasNext()) {
//this is where i stuck
}
Customer[] newCustomer = new Customer(customerName, customerMembershipType, purchaseDate, productNameList, quantityList);
customers = addCustomer(customers, newCustomer);
}
}
private static Customer[] addCustomer(Customer[] customers, Customer customerToAdd) {
Customer[] newCustomers = new Customer[customers.length + 1];
System.arraycopy(customers, 0, newCustomers, 0, customers.length);
newCustomers[newCustomers.length - 1] = customerToAdd;
return newCustomers;
}
static class Customer {
protected String customerName;
protected String customerMembershipType;
protected Date purchaseDate;
protected String[] productNameList;
protected int[] quantityList;
public Customer(String customerName, String customerMembershipType, Date purchaseDate, String[] productNameList, int[] quantityList) {
this.customerName = customerName;
this.customerMembershipType = customerMembershipType;
this.purchaseDate = purchaseDate;
this.productNameList = productNameList;
this.quantityList = quantityList;
}
}
Basically I want to create Customer objects that can hold product name lists and their quanitites' list but since arrays are immutable and Customers can have purchase unlimited amount of product type I cant find a solution without using arrayLists however i cant use it in this assignment. What can I do at this point?
I suggest instead of trying to read lines of customers AND parsing those lines, you do it separately, i.e. read lines as lines, with line per customer, and then parse lines according to your logic.
Something like the below (note I changed the Customer representation, as well as customers are now List instead of an array):
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException, ParseException {
BufferedReader reader = new BufferedReader(new FileReader(new File("shoppingList.txt")));
List<Customer> customers = new ArrayList<>();
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
Scanner shoppingList = new Scanner(line);
String customerName = shoppingList.next();
String customerMembershipType = shoppingList.next();
String purchaseDate = shoppingList.next();
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
Date date = formatter.parse(purchaseDate);
Customer customer = new Customer(customerName, customerMembershipType, date);
while (shoppingList.hasNext()) {
customer.addProduct(shoppingList.next(), shoppingList.nextInt());
}
}
}
static class Customer {
protected String customerName;
protected String customerMembershipType;
protected Date purchaseDate;
protected Map<String, Integer> products = new HashMap<>();
public Customer(String customerName, String customerMembershipType, Date purchaseDate) {
this.customerName = customerName;
this.customerMembershipType = customerMembershipType;
this.purchaseDate = purchaseDate;
}
public void addProduct(String name, int qty) {
products.put(name, qty);
}
}
}
Simplest solution I can think of is to: create a new array with bigger size (Let's say double the size of old one) when the older one is full and then copy the elements to the new array.
Reading information item by item like this has two problems: you don't know how many things the shopping list contains like you've discovered, but worse: you don't know where the shopping list ends and the data for a new customer begins.
So what I would do is read the file line by line, and split the line by the separator.
while (shoppingList.hasNextLine()) {
String line = shoppingList.nextLine();
String[] lineItems = line.split("\t");
String customerName = lineItems[0];
String customerMembershipType = lineItems[1];
String purchaseDate = lineItems[2];
// and so on
Now, you know that after these first 3 items the rest of the items are product names and quantities. You can calculate how many products there are using the size of lineItems:
int productCount = (lineItems.length - 3)/2;
String[] productNameList = new String[productCount];
int[] quantityList = new int[productCount];
Adding the values into these arrays is now simple for loop:
int itemIndex = 3;
for (int i = 0; i < productCount; i++) {
productNameList[i] = lineItems[itemIndex];
itemIndex = itemIndex + 1; // advance to next item in the line
quantityList[i] = Integer.parseInt(lineItems[itemIndex]);
itemIndex = itemIndex + 1; // advance to next item in the line
}

Getting the highest column value from csv file and storing it into arraylist

I'm trying to store into arraylistONE the Sub Name of Name that has the highest admin value.
In this case,
All-Purpose Flour it is 1 3/4 cups all-purpose flour
Baking Powder it is 1/4 teaspoon baking soda and 1/2 cup of plain
Baking Soda it is 8 teaspoons of baking powder
If a Name only has 0 admin values it should be,
Brewed Coffee it should always store the first value in the file which is 1 cup brewed coffee
And for the rest of the data that has lesser admin value, they are stored into arraylistTWO.
I'm stuck in reading the csv file and i don't know how to store into arraylistONE the Sub Name of Name that has the highest admin value and for the rest of the data that has lesser admin value, i don't know how to store into arraylistTWO.
This is the work i've done so far:
try {
br = new BufferedReader (new FileReader ("/sdcard/TABLE_BF.csv"));
while ((sCurrentline = br.readLine ()) != null) {
subIng.add(sCurrentline.split (","));
}
arrSubIng = new String[subIng.size ()][];
subIng.toArray (arrSubIng);
} catch (IOException e) {
e.printStackTrace ();
}
First of all I think it makes sense to create a simple class that holds the data since it will be easier to filter and sort using objects rather than arrays of values.
public class Ingredient {
String name;
String subName;
int status;
int admin;
public Ingredient(String name, String subName, String status, String admin) {
this.name = name;
this.subName = subName;
this.status = Integer.valueOf(status);
this.admin = Integer.valueOf(admin);
}
public String getName() {
return name;
}
public int getAdmin() {
return admin;
}
//more get and set methods here. I have only included what is needed for my answer
}
Then you read and create a list of Ingredient objects.
List<Ingredient> data = new ArrayList<>();
try {
String sCurrentline = null;
BufferedReader br = new BufferedReader(new FileReader("/sdcard/MAIN_BF.csv"));
while ((sCurrentline = br.readLine()) != null) {
String[] arr = sCurrentline.split(",");
Ingredient ingredient = new Ingredient(arr[0], arr[1], arr[2], arr[3]);
data.add(ingredient);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
Then we group the list by name into a Map
Map<String, List<Ingredient>> ingredientsByName = data.stream().collect(Collectors.groupingBy(Ingredient::getName));
And loop over that map to find the max admin value for each ingredient and add them to the correct list
List<Ingredient> main = new ArrayList<>();
List<Ingredient> other = new ArrayList<>();
//Sort on `admin` in descending order
Comparator<Ingredient> compartor = Comparator.comparing(Ingredient:: getAdmin, (i1, i2) -> {
if (i2 > i1) {
return -1;
} else if (i2 < i1) {
return 1;
}
return 0;
});
//Go through each list (ingredient) and find the one with max `admin` value
//and add it to the `main` list then add the rest to `other`
ingredientsByName.forEach( (k, group) -> {
Ingredient max = group.stream().max(compartor).get();
if (max.getAdmin() == 0) {
max = group.get(0);
}
main.add(max);
group.remove(max);
other.addAll(group);
});
I would load the entire contents of the file into memory and store it in a java.util.List<String>. Then you could sort the List by Name and admin. Then just iterate through the List. Whenever you hit a different Name, you know that its associated admin value is the largest. So you add that to your first ArrayList and all the others to your second ArrayList.

How to load records into a jTable from a file?

I'm making a GUI program, using netbeans, that is supposed to be an interface for managing records in a video store.
This is the interface. It's two tabs, and one side allows a person to add records, whilst the other tab displays them. When a person adds records, they are added to a .dat file named output. I would like to use the .dat file as a permanent storage area for the video records, and basically what I want to happen is that when one loads the GUI class, the program loads all the records from the .dat file. I have already created my code, but I'm getting the following error:
run:
java.io.EOFException
at java.io.RandomAccessFile.readChar(RandomAccessFile.java:773)
at videostore.BinaryFile.getString(BinaryFile.java:82)
at videostore.BinaryFile.load(BinaryFile.java:116)
at videostore.VideoStore.main(VideoStore.java:409)
Exception in thread "main" java.lang.NullPointerException
at videostore.VideoStore.main(VideoStore.java:420)
/Users/(my Name)/Library/Caches/NetBeans/8.1/executor-snippets/run.xml:53: Java returned: 1
BUILD FAILED (total time: 2 seconds)
And then I'll paste all relevant code below.
In the main method of the GUI class, named VideoStore.java:
file = new BinaryFile("/Users/hanaezz/Desktop/output.dat");
int length = file.length();
int ID = 1;
for (int xx = 0; xx < length; xx += file.getRecordLength()) {
Video load = file.load(xx);
String tempName = load.getVideoName();
String tempProd = load.getProducer();
String tempRat = load.getRating();
String tempGenre = load.getGenre();
short tempNum = load.getVidNum();
float tempPrice = load.getvideoPrice();
Object[] row = {ID, tempName, tempProd, tempGenre, tempRat, tempNum, tempPrice};
model.addRow(row);
ID++;
}
in the VideoStore constructor class:
public VideoStore() {
initComponents();
model = (DefaultTableModel) displayVideos.getModel();
}
And within the BinaryFile class:
private static final int RecordLength = 112;
public static Video load(int place){
String name = "", prod="", rat="", genre="";
float price = 1;
short number = 1;
try {
raf.seek(place);
name = getString(20);
prod = getString(15);
rat = getString(20);
genre = getString(10);
price = Float.parseFloat(getString(4));
number = Short.parseShort(getString(4));
writeString(20, name);
writeString(15, prod);
writeString(10, genre);
writeString(4, VideoStore.vPrice.getText());
writeString(4, VideoStore.vNumber.getText());
writeString(4, rat);
} catch (Exception e) {
e.printStackTrace();
}
Video r = new Video(name, prod, genre, rat, number, price);
return r;
}
public static int getRecordLength() throws IOException{
return RecordLength;
}
public static int length() throws IOException {
return (int)raf.length();
}
And finally, my Video class:
private static String videoName;
private static String producer;
private static String rating;
private static String genre;
private static short videoNumber;
private static float videoPrice;
public Video(String a, String b, String c, String d, short e, float f){
videoName = a;
producer = b;
rating = c;
genre = d;
videoNumber = e;
videoPrice = f;
}
...Then mutator and accessor methods for each variable in the class...
#Override
public String toString(){
return videoName + "\t" + producer +
"\t" + rating + "\t" + genre +
"\t" + videoNumber + "\t" + videoPrice;
}
So yeah, my issue is that I can't figure out how to load records from the file into the table. In my code I tried to use a loop that would iterate through each record in the file based on the record's size.. however it doesn't seem to have worked. If anyone would like to see my full code or needs more information, don't hesitate to contact me :)
First, you should use a more Object Oriented approach.
Your video class contains nothing but static attributes, when it should looks like this:
public class Video implements Serializable{
private String name;
private String producer; //consider using an object for this
private String rating; //consider using a numeric type for this
private String genre; //consider using an object for this
private int number;
private double price;
//getters and setters
}
Check the Object-Oriented Programming Concepts.
To add a new video, you get the user input from the graphic interface, and use it to create a Video object.
Video video = new Video();
video.setName(nameTextField.getText());
//same for the other attributes
Then you can keep all your videos in a List.
List<Video> videosList = new ArrayList<>();
videoList.add(video);
Then you can serialize your list to a file.
try(FileOutputStream outputFile = new FileOutputStream("/path/to/file");
ObjectOutputStream out = new ObjectOutputStream(outputFile)){
out.writeObject(videoList);
} catch (IOException e1) {
// Handle the exception
}
To read back your list from the file, you need to deserialize it:
try(FileInputStream inputFile = new FileInputStream("/path/to/file");
ObjectInputStream in = new ObjectInputStream(inputFile)){
videoList = (List<Video>)in.readObject();
} catch (IOException e1) {
// Handle the exception
}

How do I print something out according to a response in Java?

I'm new to Java and I'm making a test program. Here's the code:
import java.util.Scanner;
public class Book {
private String title;
private String author;
private String pages;
public static void main(String[] args) {
// Book #1
// =1=
Book anothermedium = new Book();
anothermedium.title = "Another Medium";
anothermedium.author = "Jen Smith";
anothermedium.pages = "387";
// Book #2
// =2=
Book whateveryouwant = new Book();
whateveryouwant.title = "Whatever You Want";
whateveryouwant.author = "Bob Gray";
whateveryouwant.pages = "424";
System.out.println("Enter the name of a book to see its details ");
System.out.println("or input Catalog to see the catalog.");
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
}
}
I'm trying to make it so when you input something like Catalog the response will be something like:
The current catalog consists of the books:
Another Medium
Whatever You Want
I'm sorry if this has already been posted. I searched and I couldn't find anything addressing my question.
Use an if-statement,
if(input.toLowerCase().equals("catalog"){
//do what you need to do here
System.out.println("The current catalog consists of the books: ");
System.out.println(anothermedium.title);
System.out.println(whateveryouwant.title);
}
To make the condition case-sensitive, the input string should be converted to lowercase. If you don't understand the syntax, basically the condition in the if-statement gets evaluated. If if evaluates to true, then whatever's in between the brackets gets exectued. If it evaluates to false, then it skips whatever's in the two brackets to proceed with the rest of the code. Hope this is what you need. Good luck!
I suggest you add each Book to a List<Book> that can looped over for the correct element, or can be used to print the entire catalogue. Something like the following implementation.
This way if you user wants a specific book the else if() can match the title and print the correct Book Otherwise if the user wants to view the enire catalogue they will only be shown the Book Titles
List<Book> listBook = new ArrayList<>();
listBook.add( whateveryouwant );
listBook.add( anothermedium );
System.out.println( "Enter the name of a book to see its details " );
System.out.println( "or input Catalog to see the catalog." );
Scanner scan = new Scanner( System.in );
String input = scan.nextLine();
for( Book book : listBook )
{
if( "catalog".equalsIgnoreCase( input ) )
{
System.out.println( "Title: " + book.getTitle() );
}
else if( book.getTitle().equalsIgnoreCase( input ) )
{
System.out.println( book.toString() );
}
}
You can create an arrayList of these book objects. Add each objects of book in that list.Run this code it should work.
public class Book {
private String title;
private String author;
private String pages;
public void Book(){
}
public String getTitle(){
return title;
}
public static void main(String[] args) {
// Book #1
// =1=
ArrayList<Book> catalog = new ArrayList<Book>();
Book anothermedium = new Book();
anothermedium.title = "Another Medium";
anothermedium.author = "Jen Smith";
anothermedium.pages = "387";
catalog.add(anothermedium);
// Book #2
// =2=
Book whateveryouwant = new Book();
whateveryouwant.title = "Whatever You Want";
whateveryouwant.author = "Bob Gray";
whateveryouwant.pages = "424";
catalog.add(whateveryouwant);
System.out.println("Enter the name of a book to see its details");
System.out.println("or input Catalog to see the catalog.");
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
if(input.equals("catalog"))
{
for(int i=0;i<catalog.size();i++)
{
System.out.println(catalog.get(i).getTitle());
}
}
}}
There are a couple different problems you're trying to solve here.
How do I conditionally display a certain output, based on the
user's input text?
How do I iterate over the contents of a List and display their names?
One thing to keep in mind is that Java is Object-Oriented. You almost always want to consider the problem you're trying to solve, and create classes that represent the various types of things within your problem space. You've described a Book entity and a Catalog entity in this case. These are usually separate classes from your main program class (that contains your main method).
You can solve the first problem by using an if statement to compare the input to a constant that your application knows about. You can solve the next problem by defining meaningful classes around your problem structure, and defining toString methods with the output that you want to see.
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class CatalogViewer {
private static final String VIEW_CATALOG_KEY = "catalog";
public static class Book {
private String title;
private String author;
private String pages;
public Book(String title, String author, String pages) {
this.title = title;
this.author = author;
this.pages = pages;
}
#Override
public String toString() {
return title;
}
}
public static class Catalog {
private List<Book> books = new ArrayList<Book>();
public List<Book> getBooks() {
return books;
}
#Override
public String toString() {
StringBuilder message = new StringBuilder();
message.append("The current catalog consists of the books:\n");
for (Book book : books) {
message.append("\n" + book + "\n");
}
return message.toString();
}
}
public static void main(String[] args) {
Catalog catalog = new Catalog();
catalog.getBooks().add(new Book("Another Medium", "Jen Smith", "387"));
catalog.getBooks().add(new Book("Whatever You Want", "Bob Gray", "424"));
System.out.println("Enter the name of a book to see its details ");
System.out.println("or input Catalog to see the catalog.");
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
if (input.trim().equalsIgnoreCase(VIEW_CATALOG_KEY)) {
System.out.println(catalog);
}
}
}

Getting nullpointerexception while using constructor

public class Author {
private int id;
private String name;
private String university;
private String department;
private String email;
private int article1;
private int article2;
private int article3;
private int article4;
private int article5;
//constructors and getter/setters are generated automatically, not adding to have space
}
This is my Author class. This class only has these attributes. Also I have a readDaFile class which is created to read author.txt and and create author objects.
import java.util.Scanner;
import java.io.*;
public class readAuthor {
private Scanner reader;
private String temp;
private String[] split;
public Author[] authorList;
private int dummyInt,dummyArticle1=0 ,dummyArticle2=0 ,dummyArticle3=0,dummyArticle4,dummyArticle5;
private int i=0;
private String name , university , department , email ;
public void tryOpeningOrDieTrying(){
try{
reader = new Scanner(new File("Author.txt"));
}
catch(Exception exo){
System.out.println("Can not find file.");
}
}
public void readDaFile(){
while(reader.hasNext()){
temp = reader.nextLine();
split = temp.split(" ");
name = "NOTGIVEN";
university = "NOTGIVEN";
department = "NOTGIVEN";
email = "NOTGIVEN";
dummyInt = 0;
dummyArticle1 = 0;
dummyArticle2 = 0;
dummyArticle3 = 0;
dummyArticle4 = 0;
dummyArticle5 = 0;
dummyInt = Integer.parseInt(split[1]);
if(split.length>2){ name = split[2]; }
if(split.length>3){ university = split[3]; }
if(split.length>4){ department = split[4]; }
if(split.length>5){ email = split[5]; }
if(split.length>6){ dummyArticle1 = Integer.parseInt(split[6]); }
if(split.length>7){ dummyArticle2 = Integer.parseInt(split[7]); }
if(split.length>8){ dummyArticle3 = Integer.parseInt(split[8]); }
if(split.length>9){ dummyArticle4 = Integer.parseInt(split[9]); }
if(split.length>10){ dummyArticle5 = Integer.parseInt(split[10]); }
System.out.println(dummyInt+name+university+department+email+dummyArticle1+dummyArticle2+dummyArticle3+dummyArticle4+dummyArticle5);
//authorList[i] = new Author(dummyInt,name,university,department,email,dummyArticle1,dummyArticle2,dummyArticle3,dummyArticle4,dummyArticle5);
i++;
//System.out.println(split[1]);
//System.out.println(split.length);
}
}
public void sealDaGates(){
reader.close();
}
}
Simply I'm reading lines first then split them into sub-elements to create author objects. But Author.txt might not give all author attributes.
For example :
AUTHOR 100
AUTHOR 101 Ruonan_Li MIT Computer_Science ruonan#mit.edu 1002001 1002009 1002004
To prevent sending null parameters to author constructor,I am initializing every attribute variable for every loop. I also checked initialized attribute variables by printf-ing them. They seem to work as intended. If I can't successfully read an attribute from txt , program sends NOTGIVEN or 0 to constructor. But still I am having nullpointerexception at line :
authorList[i] = new Author(dummyInt,name,university,department,email,dummyArticle1,dummyArticle2,dummyArticle3,dummyArticle4,dummyArticle5);
Thanks in advance
You're never initializing authorList, so that's null. It's not the constructor call which is failing - it's the assignment into the array. You need:
authorList = new Author[...];
somewhere. Alternatively - and almost certainly preferrably - use a List<Author>, e.g.
private final List<Author> authorList = new ArrayList<Author>();
Looks like you forgot to initialize the authorList array. In the constructor, add this line authorList = new Author[100]; and that should fix it. Change 100 to whatever number of elements you desire.

Categories