Java access protected variable from subclass - java

I am working on a homework assignment looking at inheritance in java. I am having a little trouble understand how to access an array in the superclass from the subclass. I looked at several other questions, and since I am so new to java, I'm still just not quite getting it.
Here is the super class
import java.text.NumberFormat;
/**
* Bank represents a single Bank containing a number of BankAccounts.
*/
public class Bank {
// Member variables:
/** The array of BankAccount objects contained in this bank. */
protected BankAccount[] myAccounts = new BankAccount[2000];
/** The number of BankAccount objects stored in the array in this bank. */
protected int numberOfAccounts = 0;
// Constructors:
/**
* Creates a Bank.
*/
public Bank() {}
// Methods:
/**
* Creates an account with the name and balance, and adds it to
* the bank's list of accounts.
* If the name already exists, no account will be created.
* #param aName The name for the new account.
* #param aBalance The initial balance for the new account.
*/
public void createAccount( String aName, double aBalance) {
BankAccount existing = this.findAccount( aName);
if( existing != null) return;
BankAccount anAccount = new BankAccount( aBalance, aName);
this.myAccounts[ numberOfAccounts] = anAccount;
this.numberOfAccounts++;
}
/**
* Finds an account in the bank's list of accounts by name.
* If no account is found, this method returns null.
* #param aName The name of the BankAccount to search for.
* #return The BankAccount bearing the given name, if found.
*/
public BankAccount findAccount( String aName) {
BankAccount answer = null;
for( int index = 0; index < numberOfAccounts; index++) {
BankAccount anAccount = this.myAccounts[ index];
if( aName.equals( anAccount.getName())) {
return( anAccount);
}
}
return( answer);
}
/**
* Returns a String which represents a short summary of
* all the accounts in the bank.
* #return A String representation of all accounts and their balances in the bank.
*/
public String toString() {
String answer = "";
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();
for( int index = 0; index < numberOfAccounts; index++) {
BankAccount anAccount = this.myAccounts[ index];
String money = currencyFormatter.format( anAccount.getBalance());
answer += anAccount.getName() + " \t" + money + "\n";
}
return( answer);
}
}
and here is the start of the subclass
public class BankSubClass extends Bank{
private double interestPaid;
// Constructor
public BankSubClass(String aName, double aBalance, double aInterest) {
super();
this.interestPaid = aInterest;
}
// Getters
public double getInterestPaid() {return(this.interestPaid);}
// Setters
public void setInterestPaid(double setInterestPaid) {this.interestPaid = setInterestPaid;}
// Other methods
public double endOfYear() {
for (i=0;i<BankAccount.length();i++) {
}
}
}
That for loop at the end are where things are getting a little tripped up. Netbeans is throwing up errors saying "cannot find symbol: variable i". Maybe this has nothing to do with the bank account array I'm trying to use, I don't know. Any help is much appreciated
Thanks for your time!
edit
So here is a continuation of the same homework
Thanks for the replies everyone, your suggestions took care of that problem, I am currently hitting another speed bump at the moment however. The idea behind this method that the for loop is in is to run through the array of BankAccount objects, check to see if any of them are of the InterestAccount type (a class I previously built) and if they are, call the yearlyUpdate() method from that class
Here is the InterestAccount class
public class InterestAccount extends BankAccount {
private double interestRate;
// Constructor
/**
* Create and interest bearing bank account with a balance, name,
* and interest rate
* #param aBalance The balance of the account
* #param aName The name tied to the account
* #param myInterestRate The interest rate of the account
*/
public InterestAccount(double aBalance, String aName, double myInterestRate) {
super(aBalance, aName);
this.interestRate = myInterestRate;
}
// Getters
/**
* Gets the interest rate of the account
* #return the interest rate of the account
*/
public double getInterestRate() {return(this.interestRate);}
// Setters
/**
* Sets the interest rate of the account
* #param interestSet The new interest rate of the account
*/
public void setInterestRate(int interestSet) {this.interestRate = interestSet;}
// Other Methods
/**
* Calculates the interest earned on the account over a year
* #return the interest earned over a year
*/
public double yearlyUpdate() {
double answer = (super.getBalance()*this.interestRate);
return answer;
}
}
Here is the super class I am currently working with
import java.text.NumberFormat;
/**
* Bank represents a single Bank containing a number of BankAccounts.
*/
public class Bank {
// Member variables:
/** The array of BankAccount objects contained in this bank. */
protected BankAccount[] myAccounts = new BankAccount[2000];
/** The number of BankAccount objects stored in the array in this bank. */
protected int numberOfAccounts = 0;
// Constructors:
/**
* Creates a Bank.
*/
public Bank() {}
// Methods:
/**
* Creates an account with the name and balance, and adds it to
* the bank's list of accounts.
* If the name already exists, no account will be created.
* #param aName The name for the new account.
* #param aBalance The initial balance for the new account.
*/
public void createAccount( String aName, double aBalance) {
BankAccount existing = this.findAccount( aName);
if( existing != null) return;
BankAccount anAccount = new BankAccount( aBalance, aName);
this.myAccounts[ numberOfAccounts] = anAccount;
this.numberOfAccounts++;
}
/**
* Finds an account in the bank's list of accounts by name.
* If no account is found, this method returns null.
* #param aName The name of the BankAccount to search for.
* #return The BankAccount bearing the given name, if found.
*/
public BankAccount findAccount( String aName) {
BankAccount answer = null;
for( int index = 0; index < numberOfAccounts; index++) {
BankAccount anAccount = this.myAccounts[ index];
if( aName.equals( anAccount.getName())) {
return( anAccount);
}
}
return( answer);
}
/**
* Returns a String which represents a short summary of
* all the accounts in the bank.
* #return A String representation of all accounts and their balances in the bank.
*/
public String toString() {
String answer = "";
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();
for( int index = 0; index < numberOfAccounts; index++) {
BankAccount anAccount = this.myAccounts[ index];
String money = currencyFormatter.format( anAccount.getBalance());
answer += anAccount.getName() + " \t" + money + "\n";
}
return( answer);
}
}
And finally, here is the subclass in which I am trying to run this for loop
public class BankSubClass extends Bank{
private double interestPaid;
// Constructor
public BankSubClass(String aName, double aBalance, double aInterest) {
super();
this.interestPaid = aInterest;
}
// Getters
public double getInterestPaid() {return(this.interestPaid);}
// Setters
public void setInterestPaid(double setInterestPaid) {this.interestPaid = setInterestPaid;}
// Other methods
public double endOfYear() {
double trackInterest=0;
for (int i=0;i<numberOfAccounts;i++) {
BankAccount working = myAccounts[i];
boolean hasInterest = working instanceof InterestAccount;
if (hasInterest) {
trackInterest = trackInterest + working.yearlyUpdate();
}
return trackInterest;
}
}
}
currently netbeans can't find the "yearlyUpdate()" method when attempting to call it on "working" what I'm not understanding is since the previous code verified that the working object was of the InterestAccount type, it should have that method available
Thanks for the help!

// Other methods
public double endOfYear() {
for (i=0;i<BankAccount.length();i++) {
}
}
You need to declare i
// Other methods
public double endOfYear() {
for (int i=0;i<BankAccount.length();i++) {
}
}

In your loop, variable i is undeclared. Also, since I think you wish to loop through the accounts in the array, I think you should be using the following:
for(int i = 0; < numberOfAccounts; i++)
{
BankAccount bankAccount = myAccounts[i];
// other stuff
}

Like the error says: i is undefined.
try:
for (int i=0;i<BankAccount.length();i++)
I'm guessing that is still bad since you want the length of the array, not the BankAccount class (which may be undefined)
for (int i=0;i<myAccounts.length();i++)

For the error, you need to define the variable i before using it in BankSubClass.endOfYear. The statement should be
for (int i=0;i<BankAccount.length();i++)

You didn't declare i in side the for loop
for (int i=0;i<BankAccount.length();i++)

Related

The operator += is undefined for the argument type(s) double, Item

I am trying to write a getter method that finds the sum of all elements in an array and returns a double. the problem is that I am passing an array of objects from another class and I am simply not aware of how to write a sum array with objects.
This is the method I'm trying to create
private double getTotal() {
double accumulator=0;
for(int i=0;i<items.length;i++) {
accumulator += items[i];
}
return accumulator;
}
And here is the class I am using
public class Item {
//class fields
private String name;
private double price;
private int quantity;
//class constructor
/**
* class constructor for Item (takes in 3 arguments and sets them appropriately)
* #param n :name
* #param p :price
* #param q :quantity
*/
public Item(String n, double p, int q) {
name =n;
price =p;
quantity =q;
}
//getters for all fields
/**
* getter method for name field of item class
* #return name
*/
public String getName() {
return name;
}
/**
* getter method for price field of item class
* #return price
*/
public double getPrice() {
return price;
}
/**
* getter method for quantity field of item class
* #return quantity
*/
public int getQuantity() {
return quantity;
}
/**
* getter method that computes sub total and returns it
* #return subTotal
*/
public double getSubTotal() {
double subTotal = price*quantity;
return subTotal;
}
//to String method
/**
* toString method for the item class
*/
public String toString() {
String output= "";
output += String.format("%10.s%5.d%5.2f%5.2f\n",name,quantity, price,subTotal );
return output;
}
}
(yes I am aware of the error in the toString method, but that's another error for another time)
in my assignment I have to use the getSubTotal() method for this. and I can not set any of my methods anywhere in my program to be static. I hope that someone can help me.
Try it with:
accumulator = items[i].getPrice();
or
accumulator = items[i].getSubTotal();

Is return a better alternative than Sys.out.print in this scenario

This is my tester class for my first programming assignment, which I believe tests the getters and setters correctly, but I was wondering if there is a better method using the return method instead. I'm still quite a novice, as this is my first programming assignment. It feels almost improper to have so many print lines, but is there a better way with return? (At least something not incredibly complex for a java beginner)
/**
A class to test the Assignment class
*/
public class AssignmentTester
{
/**
Main method used to start program
#param args the command line arguments for the program
*/
public static void main(String[] args)
{
System.out.println("TESTING NO-ARGUMENT CONSTRUCTOR AND GETTERS \n=========================================== \n");
Assignment noArgGetterTest = new Assignment();
System.out.println(noArgGetterTest.getTitle() + "\nExpected: Assignment 1 \n");
System.out.println(noArgGetterTest.getDueDate() + "\nExpected: 01/01/2019 \n");
System.out.println(noArgGetterTest.getMaxPoints() + "\nExpected: 10.0 \n");
System.out.println(noArgGetterTest.getCategory() + "\nExpected: Programming Assignments \n \n");
System.out.println("Testing Setters \n=============== \n");
Assignment setterTest = new Assignment();
setterTest.setTitle("CodeLab 1");
System.out.println(setterTest.getTitle() + "\nExpected: CodeLab 1 \n");
setterTest.setDueDate("02/09/2019");
System.out.println(setterTest.getDueDate() + "\nExpected: 02/09/2019 \n");
setterTest.setMaxPoints(5.0);
System.out.println(setterTest.getMaxPoints() + "\nExpected: 5.0 \n");
setterTest.setCategory("CodeLab, Quizzes, ICE");
System.out.println(setterTest.getCategory() + "\nExpected: CodeLab, Quizzes, ICE \n \n");
System.out.println("Testing Argument Constructor and Getters \n======================================== \n");
Assignment getterTest = new Assignment("Quiz 3.1", "03/13/2019", 2.0, "CodeLab, Quizzes, ICE");
System.out.println(getterTest.getTitle() + "\nExpected: Quiz 3.1 \n");
System.out.println(getterTest.getDueDate() + "\nExpected: 03/13/2019 \n");
System.out.println(getterTest.getMaxPoints() + "\nExpected: 2.0 \n");
System.out.println(getterTest.getCategory() + "\nExpected: CodeLab, Quizzes, ICE");
}
}
My first class file that creates the parameters and arguments for creating an assignment:
/**
Describes an assignment's title, due date, total points value, and category
*/
public class Assignment
{
private String title; //Title of assignment
private String dueDate; //Due date of assignment
private double maxPoints; //Max points of assignment
private String category; //Category of assignment
/**
Initialize instance variables for assignment project (no argument-constructor)
*/
public Assignment()
{
title = "Assignment 1";
dueDate = "01/01/2019";
maxPoints = 10.0;
category = "Programming Assignments";
}
/**
Initialize instance variables for the assignment project (argument constructor)
#param t title of assignment
#param d due date of assignment
#param m max points for the assignment
#param c category of assignment
*/
public Assignment(String t, String d, double m,String c)
{
title = t;
dueDate = d;
maxPoints = m;
category = c;
}
/**
Sets the value of title
#param t title of assignment
*/
public void setTitle(String t)
{
title = t;
}
/**
Sets the value of dueDate
#param d due date of assignment
*/
public void setDueDate(String d)
{
dueDate = d;
}
/**
Sets value of maxPoints
#param m max points of assignment
*/
public void setMaxPoints(double m)
{
maxPoints = m;
}
/**
Sets the value of category
#param c category of assignment
*/
public void setCategory(String c)
{
category = c;
}
/**
Returns the value of title
#return title of assingment
*/
public String getTitle()
{
return title;
}
/**
Returns the value of dueDate
#return due date of assignment
*/
public String getDueDate()
{
return dueDate;
}
/**
Returns the value of maxPoints
#return max points of assignment
*/
public double getMaxPoints()
{
return maxPoints;
}
/**
Returns the value of category
#return category of assingmen
*/
public String getCategory()
{
return category;
}
}
// I have done the same problem with using the return keyword, its awesome to use //return.
// but you should know "method" before using return keyword. Basically, you will know //later that the "method" helps you to save writing the same code. Cheers:)
public class AssignmentTester {
public static Assignment noArgumentConstructorAndGetters() {
System.out.println("TESTING NO-ARGUMENT CONSTRUCTOR AND GETTERS \n=========================================== \n");
Assignment noArgGetterTest = new Assignment();
return noArgGetterTest;
}
public static void printMethod(Assignment ass) {
System.out.println(ass.getTitle());
System.out.println(ass.getDueDate());
System.out.println(ass.getMaxPoints());
System.out.println(ass.getCategory());
}
public static Assignment testingSetters() {
System.out.println("Testing Setters \n=============== \n");
Assignment setterTest = new Assignment();
setterTest.setTitle("CodeLab 1");
setterTest.setDueDate("02/09/2019");
setterTest.setMaxPoints(5.0);
setterTest.setCategory("CodeLab, Quizzes, ICE");
return setterTest;
}
public static Assignment testingArgumentsAndConstructors() {
System.out.println("Testing Argument Constructor and Getters \n======================================== \n");
Assignment getterTest = new Assignment("Quiz 3.1", "03/13/2019", 2.0, "CodeLab, Quizzes, ICE");
return getterTest;
}
public static void main(String[] args) {
printMethod(noArgumentConstructorAndGetters());
printMethod(testingSetters());
printMethod(testingArgumentsAndConstructors());
}
}

How to create an ArrayList and initialize new Byte variables in it

I am currently enrolled in the Udacity Android Basics Nanodegree program.
One task now is to create a ReportCard Java Class which would allow a school to store a student’s grades for a particular year.
While I submitted my project and it successfully passed review, I was given the suggestion of using an ArrayList instead of hard-coding the subjects for which grades could be given.
While implementing this suggestion, I am extremely struggling. I already searched throught StackOverflow for hours and haven't yet found a problem-solving answer.
So, here is my code:
package com.example.android.reportcardclass;
/**
* Report Card class
* This class prepares a student report card.
*/
public class ReportCard {
/**
* Class Attributes
*/
private String mStudentName;
private int mYear;
private byte mGerman;
private byte mEnglish;
private byte mMathematics;
private byte mGeography;
private byte mSocialSciencesAndEconomics;
private byte mPhysics;
private byte mReligion;
private byte mPhysEd;
private byte mMusic;
/**
* Default Constructor for ReportCard class
*
* #param studentName Name of the student
* #param year Year in which the student is in
* #param german Mark in the subject German
* #param english Mark in the subject English
* #param mathematics Mark in the subject Mathematic
* #param geography Mark in the subject Geography
* #param socialSciencesAndEconomics Mark in the subject Social Sciences and Economics
* #param physics Mark in the subject Physcics
* #param religion Mark in the subject Religion
* #param physEd Mark in the subject Physical Education
* #param music Mark in the subject Music
*/
public ReportCard(String studentName, int year,
byte german, byte english, byte mathematics,
byte geography, byte socialSciencesAndEconomics,
byte physics, byte religion, byte physEd,
byte music) {
mGerman = german;
mEnglish = english;
mMathematics = mathematics;
mGeography = geography;
mSocialSciencesAndEconomics = socialSciencesAndEconomics;
mPhysics = physics;
mReligion = religion;
mPhysEd = physEd;
mMusic = music;
}
/**
* This method is to get Student Name
*
* #return Student Name
*/
public String getStudentName() {
return mStudentName;
}
/**
* This method is to set Student Name
*
* #param studentName Name of the student
*/
public void setStudentName(String studentName) {
mStudentName = studentName;
}
/**
* This method is to get the year in which the student is in
*
* #return Year in which the student is in
*/
public int getYear() {
return mYear;
}
/**
* This method is to set the year in which the student is in
*
* #param year Year in which the student is in
*/
public void setYear(int year) {
mYear = year;
}
/**
* These are the setter and getter methods for the marks of the student in the respective subject
*/
public byte getGerman() {
return mGerman;
}
public void setGerman(byte german) {
mGerman = german;
}
public byte getEnglish() {
return mEnglish;
}
public void setEnglish(byte english) {
mEnglish = english;
}
public byte getMathematics() {
return mMathematics;
}
public void setMathematics(byte mathematics) {
mMathematics = mathematics;
}
public byte getGeography() {
return mGeography;
}
public void setGeography(byte geography) {
mGeography = geography;
}
public byte getSocialSciencesAndEconomics() {
return mSocialSciencesAndEconomics;
}
public void setSocialSciencesAndEconomics(byte socialSciencesAndEconomics) {
mSocialSciencesAndEconomics = socialSciencesAndEconomics;
}
public byte getPhysics() {
return mPhysics;
}
public void setPhysics(byte physics) {
mPhysics = physics;
}
public byte getReligion() {
return mReligion;
}
public void setReligion(byte religion) {
mReligion = religion;
}
public byte getPhysEd() {
return mPhysEd;
}
public void setPhysEd(byte physEd) {
mPhysEd = physEd;
}
public byte getMusic() {
return mMusic;
}
public void setMusic(byte music) {
mMusic = music;
}
#Override
public String toString() {
return "Student Name: " + getStudentName() + "\nYear: " + getYear() + "German: "
+ getGerman() + "\nEnglish: " + getEnglish() + "\nMathematics: " +
getMathematics() + "\nGeography: " + getGeography() +
"\nSocialSciencesAndEconomics: " + getSocialSciencesAndEconomics() +
"\nPhysics: " + getPhysics() + "\nReligion: " + getReligion() +
"\nPhysical Education: " + getPhysEd() + "\nMusic: " + getMusic();
}
}
What I want to do now, is to store the class attributes initialized at the very beginning (mGerman, mEnglish, etc.) in an ArrayList. How do I do that?! I am extremely struggling as I don't want to set any values just yet, but simply initialize the byte values (grading system in Germany goes from 0 to 15 points).
Please help me, thank you very much in advance!
If you know how many grades there are going to be you can use the following to initialize an ArrayList with null values:
List<Byte> bytes = new ArrayList<Byte>(Arrays.asList(new Byte[9]));
To update values in the List you can use for example
bytes.set(3, (byte) 12);
Try this
ArrayList<ReportCard> mList=new ArrayList<>();
ReportCard reportCard=new ReportCard();
reportCard.setStudentName("student name");
//fill all the details like this
reportCard.setYear("2017");
.
.
mList.add(reportCard);
And when you want to get the details do like this
String studentName=mList.get(position).getStudentName();
I suggest you to use an EnumSet instead of a list to store the grades, for the following reasons:
It provides a more compact representation in memory
It only accepts values of well-defined grades thanks to enum
It prevents duplicates
It allows to check if a grade is present with O(1) complexity.
First define an enum with the grades:
public enum Grade {
GERMAN, ENGLISH, MATHEMATICS, GEOGRAPHIC, SOCIAL_SCIENCES_AND_ECONOMICS,
PHYSICS, RELIGION, PHYSICAL_EDUCATION, MUSIC
}
Then you can expose methods to add or remove a grade for example, that will delegate to the EnumSet methods:
private final EnumSet<Grade> grades = EnumSet.noneOf(Grade.class);
public boolean add(Grade grade) {
return grades.add(grade);
}
public boolean remove(Grade grade) {
return grades.remove(grade);
}

Write a Java program for an inventory report using objects created from a text file

I had a project for school that I could just not get to compile correctly.
The instructions can be found at this link.
I believe I have the class created correctly in Product.java. My code is below:
import java.util.*;
public class Product {
// Private member variables go here - you will need to add them yourself.
private String name;
private String code;
private int quantity;
private double price;
private String type;
private ArrayList<Integer> userRatings;
/*
* Product constructor
*/
public Product() {
name = "";
code = "";
quantity = 0;
price = 0;
type = "";
userRatings = new ArrayList<Integer>();
}
/*
* setName
* #param name - new name for the product
*/
public void setName(String name) {
this.name = name;
}
/*
* getName
* #return the name of the product
*/
public String getName() {
return name;
}
/*
* setType
* #param type - the type of the product
*/
public void setType(String type) {
this.type = type;
}
/*
* getType
* #return - the product type
*/
public String getType() {
return type;
}
/*
* setPrice
* #param price - the price of the product
*/
public void setPrice(double price) {
this.price = price;
}
/*
* getPrice
* #return the price of the product
*/
public double getPrice() {
return price;
}
/*
* setQuantity
* #param quantity - the number of this product in inventory
*/
public void setQuantity(int quantity) {
this.quantity = quantity;
}
/*
* getQuantity
* #return the number of this product in inventory
*/
public int getQuantity() {
return quantity;
}
/*
* setInventoryCode
* #param code - the new inventory code for the product
*/
public void setInventoryCode(String code) {
this.code = code;
}
/*
* getInventoryCode
* #return the inventory code of the product
*/
public String getInventoryCode() {
return code;
}
/*
* addUserRating
* NOTE: Each individual rating is stored with the product, so you need to maintain a list
* of user ratings. This method should append a new rating to the end of that list
* #param rating - the new rating to add to this product
*/
public void addUserRating(int rating) {
userRatings.add(rating);
}
/*
* getUserRating
* NOTE: See note on addUserRating above. This method should be written to allow you
* to access an individual value from the list of user ratings
* #param index - the index of the rating we want to see
* #return the rating indexed by the value index
*/
public int getUserRating(int index) {
return userRatings.get(index);
}
/*
* getUserRatingCount
* NOTE: See note on addUserRating above. This method should be written to return
* the total number of ratings this product has associated with it
* #return the number of ratings associated with this product
*/
public int getUserRatingCount() {
return userRatings.size();
}
/*
* getAvgUserRating
* NOTE: see note on addUserRating above. This method should be written to compute
* the average user rating on demand from a stored list of ratings.
* #return the average rating for this product as a whole integer value (use integer math)
*/
public int getAvgUserRating() {
int sum = 0;
if(userRatings.size() > 0){
for (int i = 0; i < userRatings.size(); i++){
sum += userRatings.get(i);
}
return sum / userRatings.size();
}
else return 0;
}
}
But the problem lies within the test code. I have tried multiple ways and keep getting the same InputMismatchException error. I will need an ArrayList of Product objects for part 2 so I tried to incorporate that into the test code. Below is ProductTest.java:
import java.util.*;
import java.io.*;
public class ProductTest {
/*
* A simple main loop to load product objects from a file
* and then display them to the console
*/
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter an inventory filename: ");
String fname = keyboard.nextLine();
ArrayList<Product> products = loadProducts (fname);
displayProducts(products);
}
/*
* loadProducts
* Given a filename, opens the file and reads Products from
* the file into an ArrayList of Product objects. Returns the
* Arraylist.
*
* #param fname - String containing the input file name
* #return - An ArrayList of Product objects
*/
public static ArrayList<Product> loadProducts(String fname) {
ArrayList<Product> products = new ArrayList<Product>();
try {
Scanner inFile = new Scanner(new File(fname));
while (inFile.hasNext()) {
Product pr = new Product();
pr.setName(inFile.next());
pr.setInventoryCode(inFile.next());
pr.setQuantity(inFile.nextInt());
pr.setPrice(inFile.nextDouble());
pr.setType(inFile.next());
while(inFile.nextInt() != -1){
pr.addUserRating(inFile.nextInt());
}
products.add(pr);
}
inFile.close();
}
catch(IOException e) {
System.out.println("ERROR: "+e);
}
return products;
}
/*
* displayProducts
* Given an ArrayList of Product objects, outputs them
* to the console in the specified format.
*
* The format for this method is:
* NAME, INVENTORY_CODE, QUANTITY, PRICE, TYPE, RATING
*
* #param products - ArrayList of Product objects
*/
public static void displayProducts(ArrayList<Product> products) {
for(int i = 0; i<products.size(); i++) {
Product tmpProduct = products.get(i);
System.out.println(tmpProduct.getName());
System.out.println(tmpProduct.getInventoryCode());
System.out.println(tmpProduct.getQuantity());
System.out.println(tmpProduct.getPrice());
System.out.println(tmpProduct.getType());
System.out.println(tmpProduct.getAvgUserRating());
System.out.println();
}
}
}
This is the error message that results from running the current ProductTest:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at osu.cse2123.ProductTest.loadProducts(ProductTest.java:46)
at osu.cse2123.ProductTest.main(ProductTest.java:23)
The text file I'm using contains the following:
The Shawshank Redemption
C0000001
100
19.95
DVD
4
5
3
1
-1
The Dark Knight
C0000003
50
19.95
DVD
5
2
3
-1
Casablanca
C0000007
137
9.95
DVD
5
4
5
3
-1
The Girl With The Dragon Tattoo
C0000015
150
14.95
Book
4
4
2
-1
Vertigo
C0000023
55
9.95
DVD
5
5
3
5
2
4
-1
A Game of Thrones
C0000019
100
8.95
Book
-1
Any help on the issues would be much appreciated.
You are reading one word at a time. Currently your file is being read by the Scanner like this:
inFile.next() = The
inFile.next() = Shawshank
Tip: inFile.nextLine() = The Shawshank Redeption
You problem is in the while loop reading ratings:
while(inFile.nextInt() != -1){
pr.addUserRating(inFile.nextInt());
}
Each round of the loop reads two items - one in the while condition, and another one inside the loop. Since there's a String (the next title) after the ratings end, if there was an even number of ratings you'd fail here when trying to interpret it as an int (and if it doesn't fail you'd just get the wrong result, since you're skipping half the ratings). One way to fix this is to extract the rating to a local variable:
int rating;
while(rating = inFile.nextInt() != -1){
pr.addUserRating(rating);
}
I suggest you realise how many times you are invoking readInt consecutively. Imagine an alternative way to read a value, check it, and reuse it without re-reading.
Without a better formating of your file (no end of line), you need to use a regex matching :
Something like this :
public static ArrayList<Product> loadProducts(String fname) {
ArrayList<Product> products = new ArrayList<Product>();
Pattern p = Pattern.compile("([\\w ]*) (C[0-9]*) (\\d*) ([\\d\\.]*) (\\w*) ([\\d -]*)");
Matcher m = p.matcher(fname);
while (m.find()) {
Product pr = new Product();
pr.setName(m.group(1));
pr.setInventoryCode(m.group(2));
pr.setQuantity(Integer.parseInt(m.group(3)));
pr.setPrice(Double.parseDouble(m.group(4)));
pr.setType(m.group(5));
for (String rate : m.group(6).split(" ")) {
pr.addUserRating(Integer.parseInt(rate));
}
products.add(pr);
System.out.println(pr);
}
return products;
}
The InputMismatchException occurs when you call nextDouble() or nextInt() from a Scanner instance while instead you enter something other than a number. The error message shows that the flaw lies within the loadProducts method.
In that method you make a call to next() to get product name and inventory code. However, since your product name contains spaces, you should call nextLine() instead.
What happens in your program is this: Calling next() on "The Shawshank Redemption" will return "The". By the time you reach pr.setQuantity(inFile.nextInt()); your program will throw the InputMismatchException because it tries to read an integer from "Redemption".
Also take into account the advice from mureinik:
https://stackoverflow.com/a/25936439/4056420

2d Array containing objects

This is an assignment for class that involves creating a hotel guest service. I created the 2d array below with 8 "floors", 20 "rooms", and populated them with Room objects. I am currently trying to use nested for-loops to go through each Room object and assign it a room number. For example, floor 1 would contain rooms 101-120.
The class below is a test class that I am using.
public class Test {
public Test() {
}
public static void main(String[] args) {
/**
* Creates a two dimensional array with 8 rows and 20 columns
*/
Room [][] hotelBuild = new Room[8][20];
/**
* populates the 2d array with Room objects
*/
for (int floor=0; floor<hotelBuild.length; floor++) {
for (int room=0; room<hotelBuild[floor].length; room++) {
hotelBuild[floor][room] = new Room();
/**
* used to print out contents of 2d array
*/
//System.out.print(hotelBuild[floor][room]=new Room());
}
}
}
}
Below is class Room that contains the variables, setters, getters, as well as the toString() override method.
public class Room {
//Instance variables
/**
*the rooms number
*/
private int roomNumber;
/** is the room occupied or not
*
*/
private boolean isOccupied;
/** name of guest
*
*/
private String guest;
/** cost per day
*
*/
private double costPerDay;
/** number of days guest is staying
*
*/
int days;
//Constructors
public Room(){
}
/** Construct a room with values above
*
*/
public Room(int room, boolean nonVacant, String guestName, double cost, int day) {
roomNumber = room;
isOccupied = nonVacant;
guest = guestName;
costPerDay = cost;
days = day;
}
// getters
/** gets roomNumber
*
*/
public int getRoomNumber(){
return roomNumber;
}
/** gets isOccupied
*
*/
public boolean getIsOccupied(){
return isOccupied;
}
/** gets guest
*
*/
public String getGuest(){
return guest;
}
/** gets costPerDay
*
*/
public double getCostPerDay(){
return costPerDay;
}
/** gets days
*
*/
public int getDays(){
return days;
}
// setters
/** sets isOccupied
*
*/
public void setIsOccupied(boolean full){
this.isOccupied = full;
}
/** sets days
*
*/
public void setDays(int numDays){
this.days = numDays;
}
/** sets guest name
*
*/
public void setGuest(String name){
this.guest = name;
}
/** formats output depending if room is occupied or not
*
*/
public String toString(){
if(isOccupied == true){
return "Room number: " + roomNumber + "\n"+ "Guest name: "
+ guest + "\n"+ "Cost : " + costPerDay
+ "\n"+ "Days: " + days + "\n";
}
else{
return "Room number " + roomNumber
+ " costs " + costPerDay + "\n";
}
}
}
How do I assign each Room object in the array a unique room number?
You could do
for (int floor=0; floor<hotelBuild.length; floor++){
for (int room=0; room<hotelBuild[floor].length; room++){
Room r = new Room();
r.setRoomNumber(
cleverCalculationWithFloorAndRoomNr(floor, room));
hotelBuild[floor][room]= r;
If you want a way to put the numbers in the correct order then use the varables you alredady have. Use a count for know what floor it is (it will be increased at the end of the first loop). Then room number is Floor * 100 + another variable you reset to 1 at the begining of the first loop. Just a hint to help you. Fill the gaps ;)
int floorNumber = 1;
int roomNumber = 1;
for (int floor=0; floor<hotelBuild.length; floor++){
for (int room=0; room<hotelBuild[floor].length; room++){
hotelBuild[floor][room]=new Room();
/**
* used to print out contents of 2d array
*/
//System.out.print(hotelBuild[floor][room]=new Room());
//Add room number here.
//Increase room number
}
//floorNumber increase
//roomNumber reset
}
Once you have achieved this you could try to use the variables you have in the loops (room and floor) with a few minor changes.
for (int floor=0; floor<hotelBuild.length; floor++){
for (int room=0; room<hotelBuild[floor].length; room++){
hotelBuild[floor][room]=new Room();
// room number format: xxyy, x = floor, y = room
// this assumes maximum 99 rooms per floor, it should be enough
hotelBuild[floor][room].setNumber((floor + 1) * 100 + room + 1);
}
}
You can pass it through the contructor for example or set with a setter in your class Room (classroom ahahah)
for example:
for (int floor=0; floor<hotelBuild.length; floor++){
for (int room=0; room<hotelBuild[floor].length; room++){
hotelBuild[floor][room]=new Room((floor+1)*100+room+1);
}
}
And in your Room class, you can add a constructor with only the room number as parameter
class Room{
public Room(int roomNumber){
this.roomNumber = roomNumber;
}
...
}

Categories

Resources