My Null pointer exception - java

I am working on a simple program for my intro to Object Oriented programing class, where I have 3 classes: Account, ATM and the main/Runner class.
I am experiencing a null pointer exception error in the constructor of the ATM class when I am trying to initialize the array of Accounts using a loop. I am new to Java so I don't really know what happens.
Here is the code:
import java.util.Date;
public class Account {
private int account_id;
private double account_balance;
private static double annual_interest_rate;
private Date date_Created;
Account(){
account_id = 0;
account_balance=0;
annual_interest_rate = 0;
date_Created = new Date();
}
Account(int account_id_in,
double account_balance_in, double annual_interest_rate_in) {
account_id = account_id_in;
account_balance = account_balance_in;
annual_interest_rate = annual_interest_rate_in;
date_Created = new Date();
}
int get_account_id(){
return account_id;
}
double get_account_balance(){
return account_balance;
}
double get_annual_interest_rate(){
return annual_interest_rate;
}
Date get_date_created(){
return date_Created;
}
void set_account_id(int account_id_in){
account_id = account_id_in;
}
void set_account_balance(double account_balance_in){
account_balance = account_balance_in;
}
void set_annual_interest_rate(double annual_interest_rate_in){
annual_interest_rate = annual_interest_rate_in;
}
double get_monthly_interest_rate(){
return annual_interest_rate/12;
}
double get_monthly_interest(){
return (account_balance * get_monthly_interest_rate())/100;
}
void perform_deposit(double deposit_in){
account_balance += deposit_in;
}
void perform_withdraw(double withdraw_amount){
account_balance -= withdraw_amount;
}
}
public class ATM {
private Account[] acct = new Account [10];
public ATM(){
//acct = new Account[10];
for(int i = 0; i<10 ; i++){
acct[i].set_account_id(i+1);
acct[i].set_account_balance(100); // here iam getting an error.
}
//you must set their ids to values as specified in the assignment
} //these are the teacher's comments and instructions.
public void displayMenu(){
System.out.println("ATM Menu:");
System.out.println("\tenter 1 for viewing the current balance");
System.out.println("\tenter 2 for withdrawing money");
System.out.println("\tenter 3 for for depositing money");
System.out.println("\tenter 4 for exiting the main menu");
}
public boolean checkID(int id){
for(int i = 0; i<10 ; i++){
if(acct[i].get_account_id() == id){
return true;
}
}
return false;
}
public double checkBalance(int idToSearch){
int indexOfAccountToReturn = 0;
for(int i = 0; i<10; i++){
if(acct[i].get_account_id() == idToSearch){
indexOfAccountToReturn = i;
break;
}
}
return acct[indexOfAccountToReturn].get_account_balance();
}
public void withdrawFunds(int id, double amount){
for(int i=0; i<10; i++){
if(acct[i].get_account_id() == id){
acct[i].perform_withdraw(amount);
break;
}
}
}
public void depositFunds(int id, double amount){
for(int i=0; i<10; i++){
if(acct[i].get_account_id() == id){
acct[i].perform_deposit(amount);
break;
}
}
}
}
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Banking_Finance_Main {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ATM atm = new ATM();
Scanner input = new Scanner(System.in);
do{
System.out.println("Account ID?");
int id = input.nextInt();
while(!(atm.checkID(id))){
String entry =
JOptionPane.showInputDialog("Incorrect Input");
id = Integer.parseInt(entry);
}
//prevent user to proceed without the correct id; use checkID method and store appropriately
do{
atm.displayMenu();
System.out.println("Your choice?");
int choice = input.nextInt();
while((choice >4) || (choice <1)){
String entry = JOptionPane.showInputDialog("Incorrect Imput");
choice = Integer.parseInt(entry);
}
//prevent user to proceed without the correct choice 1-4;
if(choice==1){
System.out.println("Enter the Account id to check the balance: ");
int idToSearch = input.nextInt();
System.out.println("The balance in this ACccount is: $" + atm.checkBalance(idToSearch));
}else if(choice==2){
System.out.println("Enter the Account id to perform withdrawal: ");
int idToSearch = input.nextInt();
System.out.println("Enter the amount to be withdrawn: ");
double amountToWithdraw = input.nextDouble();
atm.withdrawFunds(idToSearch, amountToWithdraw);
}else if(choice==3){
System.out.println("Enter the Account id to perform deposit: ");
int idToSearch = input.nextInt();
System.out.println("Enter the amount to be deposited: ");
double amountToDeposit = input.nextDouble();
atm.depositFunds(idToSearch, amountToDeposit);
}else{
break;
}
}while(true);
}while(true);
}
}
I am sorry if I am using this site inappropriately, this is my first question here so bear with me please.
I managed to pass through the error with the following fix:
public ATM(){
for(int i = 0; i<10 ; i++){
acct[i] = new Account();
acct[i].set_account_id(i+1);
acct[i].set_account_balance(100);
}
//you must set their id's to values as specified in the assignment
}
However I am not sure if this is correct or not. Is it?

The problem here is that this line:
private Account[] acct = new Account [10];
only initializes space for 10 Account instances, it doesn't actually construct 10 account instances and put them in the array.
In the for loop in your ATM constructor, you need to first call acct[i] = new Account();

Beside creating array you also need to fill it with objects. Update your code in ATM constructor:
for (int i = 0; i < 10; i++) {
acct[i] = new Account(); // add this line to crate account
// and place it in array
acct[i].set_account_id(i + 1); // also you are getting error here
acct[i].set_account_balance(100); // not here because you ware trying to
// invoke method on `null`
}

Related

Giving random numbers to object in separate class

I had made a program that creates 10 basic accounts with an ID consisting of four digits and a default balance of 100.I am attempting to create additional accounts(checking accounts) with more restrictions/additional information.In order to access the accounts, you must enter your id which is displayed in a list of all possible id's(to avoid guessing id's).My issue is now that I have created 10 Checkingaccount objects with my initial 10 standard account objects my program will not assign a random four digit ID to both objects.object accounts gets ID's fine but if you run the program the Checkingaccount objects receive no ID's.Why?
I have tried for hours and I am very new to this so please forgive me if this is in some way broken or incorrect.I really appreciate the time you take to give me help!
import java.util.Scanner;
import java.util.Random;
public class Chapter10_7 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
CheckingAccount[] Checkingaccount = new CheckingAccount[10];//create ten CHECKING ACCOUNT objects
account[] accounts = new account[10];//create ten accounts objects
for (int i = 0; i < accounts.length; i++) {
Random r = new Random();
int ID = +((int)(Math.random()*9000)+1000);//ID is 4 digit number
accounts[i] = new account(ID, 100); //assign random 4 digit ID to accounts[1-10]
System.out.println(ID);
}
System.out.println("\n--Checking Accounts--\n");
for (int i = 0; i < Checkingaccount.length; i++) {
Random r = new Random();
int ID = +((int)(Math.random()*9000)+1000);//ID is 4 digit number
Checkingaccount[i] = new CheckingAccount(ID, 100); //assign random 4 digit ID to CHECKING ACCOUNT[1-10]
System.out.println(ID);
}
boolean hasRan = false;
int q = 0;
int a = q;
int userID = 0;
int accountID = 0;
int CheckingaccountID = 0;
int z = 0;
while(z != 4){//run until user enters 4
while(hasRan == false){//runs once and never again unless its incorrect ID
System.out.println("Enter Account ID");
userID = input.nextInt();
for(a = 0; a < accounts.length; a++){
accountID = accounts[a].getId(); //accountID gets accounts[a] ID variable and stores it(4 digit ID).getId
CheckingaccountID = Checkingaccount[a].getId();
if(userID == accountID){//if your input of ID equals an accounts pin(any of them) it allows access
System.out.println("Welcome");
hasRan = true;//stops it from looping
break;
}if(userID == CheckingaccountID){//if your input of ID equals a Checking Account pin(any of them) it allows access
System.out.println("Welcome");
hasRan = true;//stops it from looping
break;
}else if(userID != accountID){
hasRan = true;//loop if you entered incorrect pin
}
}
}
if(userID == accountID){// if ID matches an existing accounts ID then access
System.out.println("\n1:Check Balance\n2:Deposit\n3:Withdraw\n4:Exit");
int x = input.nextInt();
//accounts[a] is the account array,1-10 since we have 10 accounts.
if (x == 1){
System.out.println("Your Balance Is: " + accounts[a].getBalance());
accounts[a].getBalance();
}else if (x == 2){
System.out.println("How Much Would You Like To Deposit?");
int newDeposit = input.nextInt();
accounts[a].deposit(newDeposit);
System.out.println("Your Total Is: "+ accounts[a].getBalance());
}else if(x == 3){
System.out.println("How Much Would You Like To Withdraw?");
int newWithdraw = input.nextInt();
accounts[a].withdraw(newWithdraw);
System.out.println("Your Total Is: "+ accounts[a].getBalance());
}else break;
}else{
hasRan = false;// allows ID check to run again
}
}
}
}
-This is the class I created to use only 10 basic "accounts" objects.
class account{
private int id = 0;
private double balance = 100;
public account(int newId , double newBalance ){
id = newId;
balance = newBalance;
}
public double getBalance() {
return balance;
}
public void setBalance(double newBalance) {
balance = newBalance;
}
public int getId() {
return id;
}
public void setId(int newId) {
id = newId;
}
public double deposit(double newDeposit){
balance = balance + newDeposit;
return newDeposit;
}
public double withdraw(double newWithdraw){
balance = balance - newWithdraw;
return newWithdraw;
}
#Override
public String toString() {
return "\r\n"+"Account ID: " + id + "\r\n" + "Balance: " + balance + "\r\n" ;
}
}
-I tried to make Checking Accounts work in a seperate class from accounts
import java.util.Random;
public class CheckingAccount {
private double balance;
private int id;
public CheckingAccount(int newId , double newBalance){
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public int getId() {
return id;
}
public void setID(int newId){
id = newId;
}
}
Your Question accounts gets ID's fine but if you run the program the Checkingaccount objects receive no ID's.Why?
You create the object like
new CheckingAccount(ID, 100);
but your constructor is wrong and is not saving the passed values
You should change it to
public CheckingAccount(int newId , double newBalance){
this.id = newId;
balance = newBalance;
}
Also,why are you instantiating
Random r = new Random();
when you never use it.

Copy Constructor Test not Working (Java)

I'm working on CS homework and have run into a problem. The end of the homework asks about using a copy constructor. The goal is to "make one Payroll object, instantiate it, make a second one, then print them both. Then, change values in the second Payroll object, and show that the changed values only appear in one and not both (that is, print out the original and the copy with slightly changed values)." I tried changing the values in the second Payroll object, but it also changes it in the first. I've listed my code below:
import java.util.Random;
public class Payroll {
private int[] employeeId;
private int[] hours;
private double[] payRate;
public Payroll(){
this.employeeId = new int[0];
this.hours = new int[0];
this.payRate = new double[0];
}
public Payroll(Payroll obj){
this.employeeId = obj.employeeId;
this.hours = obj.hours;
this.payRate = obj.payRate;
}
public Payroll(int i){
this.employeeId = new int[i];
this.hours = new int[i];
this.payRate = new double[i];
}
public int getEmployeeIdAt(int index){
return employeeId[index];
}
public int getHoursAt(int index){
return hours[index];
}
public double getPayRateAt(int index){
return payRate[index];
}
public double getGrossPay(int index){
double grossPay = hours[index] * payRate[index];
grossPay = Math.round(grossPay * 100);
return grossPay/100;
}
public void setEmployeeIdAt(int index, int id){
this.employeeId[index] = id;
}
public void setHoursAt(int index, int hrs){
this.hours[index] = hrs;
}
public void setPayRateAt(int index, double pr){
this.payRate[index] = pr;
}
public void setHoursAt(int i){
Random rand = new Random();
int randHours = rand.nextInt((50 - 15) + 1) + 15;
this.hours[i] = randHours;
}
}
import java.util.Scanner;
public class PayrollDriver {
public static void main(String[] args) {
Payroll pr = new Payroll(5);
Scanner scan = new Scanner(System.in);
int empID = 1001;
for(int i = 0; i < 5; i++){
pr.setEmployeeIdAt(i, empID);
empID++;
}
for(int i = 0; i < 5; i++){
System.out.println("Enter the hourly pay rate for employee number " + pr.getEmployeeIdAt(i) + ": ");
double payRate = scan.nextDouble();
if(payRate < 7.50){
do{
System.out.println("ERROR: Enter 7.50 or greater for pay rate: ");
payRate = scan.nextDouble();
} while(payRate < 7.50);
}
pr.setPayRateAt(i, payRate);
pr.setHoursAt(i);
}
System.out.println("PAYROLL DATA");
System.out.println("======================");
for(int i = 0; i < 5; i++){
System.out.println("Employee ID: " + pr.getEmployeeIdAt(i) + " Hours: " + pr.getHoursAt(i) + " Rate: " + pr.getPayRateAt(i) +
" Gross Pay: $" + pr.getGrossPay(i));
}
System.out.println("Would you like to run the Copy Constructor Test? Enter 'y' (lowercase) if yes, enter any other letter if no: ");
char copyTestVerify = scan.next().charAt(0);
if(copyTestVerify == 'y'){
CopyConstructorTest ct = new CopyConstructorTest();
ct.CopyTest();
}
scan.close();
}
}
The following is my CopyConstructorTest class, the one that tests whether or not the copy constructor will change the original object's values:
public class CopyConstructorTest {
public void CopyTest(){
Payroll pay = new Payroll(5);
pay.setEmployeeIdAt(0, 1001);
Payroll payCopy = new Payroll(pay);
System.out.println("Original: " + pay.getEmployeeIdAt(0));
System.out.println("Copy: " + payCopy.getEmployeeIdAt(0));
payCopy.setEmployeeIdAt(0, 5000);
System.out.println("Original after changes: " + pay.getEmployeeIdAt(0));
System.out.println("Copy after changes: " + payCopy.getEmployeeIdAt(0));
}
}
I'm not positive on what I'm doing wrong. Any help or guidance is much appreciated.
You are just copying the references to the arrays, not the actual data. Therefore whenever you change the data in one of your objects, the changes are seen in both, since they point to the same array.
The easiest way to copy the data is probably using System.arraycopy():
public Payroll(Payroll obj) {
this.employeeId = new int[obj.employeeId.length];
System.arraycopy(obj.employeeId, 0, this.employeeId, 0, obj.employeeId.length);
...

Store/ Display Data Inputs from Arrays

I'm having problems on how and where to put arrays.
I figured out how and where to put a loop so it will keep on gathering multiple user data that will be stored inside the arrays but I don't know where to put arrays. There will be an array for product numbers, an array for product name, and an array for price.
import java.io.*;
public class DataInsideArrays
{
public static DataInputStream a = new DataInputStream(System.in)
public static void main(String args[])throws Exception
{
int y = 0;
for(int x=1;x<=100;x++)
{
System.out.println("1 - Maintenance");
System.out.println("2 - Transaction");
System.out.println("");
System.out.print("Enter code: ");
int code =
Integer.parseInt(a.readLine());
System.out.println("");
if(code==l)
{
System.out.print("") ;
System.out.print("Product number: ");
System.out.print("Product name: ");
String prodname = a.readLine();
System.out.print("Price: ");
int price = Integer.parseInt(a.readLine());
System.out.println("");
}
else if(code==2)
{
System.out.println("Display List of Products-Prices")
System.out.print("Enter product number:
") ;
int prodnum
Integer.parseInt(a.readLine());
System.out.println("")
}
if(code==3)
{
System.out.println("Invalid");
System.out.println("Restart");
System.out.println("");
}}}}
First of all, where do you get this l (lowercase L) value in your for loop? Shouldn't this be 1 (number one)? Furthermore, it would be even better if it is 0 (zero) so you can use it as an index for your array.
Second thing, what's the point of int y = 0'? You are not using y anywhere in your program.
int y = 0;
for(int x = l; x <= 100; x++)
Change it to:
for(int x = 0; x < 100; x++)
Since you want to have 3 separate arrays, you should have 3 separate indexes to keep track of them.
Now let's see how to initialize an array to store the data. You should declare the size as a variable at the top of your class (or locally in your main()) to make it easier to change it later across your program. You can do the same with your array. Declare it inside your class or locally inside the main(). I will show you how to declare both outside of the class, but you should try it the other way too for practice.
Now remember, when using arrays you have to know the size of the array in advance as soon as you create it and you cannot change that size after. This means only that many elements can fit inside the array. If you want variable size structures, check out some of the answers with ArrayLists.
public class DataInsideArrays
{
public static DataInputStream a = new DataInputStream(System.in)
public static int size = 100; // now you only change this number and everything works
public static int[] productNumbers = new int[size];
public static String[] productNames = new String[size];
public static int[] productPrices = new int[size];
public static void main(String args[]) throws Exception
{
int prodnumIndex = 0; // index for tracking product numbers
int prodnameIndex = 0; // index for tracking product names
int prodpriceIndex = 0; // index for tracking product prices
for(int x = 0; x < size; x++)
{
// ... your code...
// ...
int prodNum = Integer.parseInt(a.readLine());
// check if we didn't reach our maximum size
if(prodnumIndex < productNumbers.length) {
productNumbers [prodnumIndex] = prodnum;
prodnumIndex++; // increment
} else {
System.out.println("Cannot add product number. Reached maximum amount.");
}
// ...
String prodName = a.readLine();
// check if we didn't reach our maximum size
if(prodnameIndex < productNames.length) {
productNames [prodnameIndex] = prodName ;
prodnameIndex++; // increment
} else {
System.out.println("Cannot add product name. Reached maximum amount.");
}
// ...
int prodPrice = Integer.parseInt(a.readLine());
// check if we didn't reach our maximum size
if(prodpriceIndex < productPrices.length) {
productPrices [prodpriceIndex] = prodPrice ;
prodpriceIndex++; // increment
} else {
System.out.println("Cannot add product number. Reached maximum amount.");
}
// ...
}
Another way you can achieve this is to create an object called Product that will contain the properties you need and then have an array of that object.
class Product {
int num;
String name;
int price;
Product(int num, String name, int price) {
this.num = num;
this.name = name;
this.price = price;
}
}
// ...
// declare your array of `Product` objects...
Product[] products = new Product[size];
// ...
// then you can do something like
System.out.println("Enter product number:");
int prodNum = Integer.parseInt(a.readLine());
System.out.println("Enter product name:");
String prodName = a.readLine();
System.out.println("Enter product price:");
int prodPrice = Integer.parseInt(a.readLine());
products[INDEX] = new Product(prodNum, prodName, prodPrice);
// ...
Also, consider using a double of a float for the product price since it is more realistic representation of actual products.
Do you have to use an array and "if" statements?
Common practice is to use a List as switch statement:
int[] productArray = new int[100];
List<Integer> productList = new ArrayList<Integer>();
for(int x=1;x<=100;x++) {
switch (code){
case 1:
productArray[x-1] = Integer.parseInt(a.readLine());
productList.add(new Integer(a.readLine()) );
break;
default:
System.out.println("Invalid")
break;
}
}
You should use a List instead of an array, because you don't know a priori the length for them.
A List allows you to dinamically add an element as soon as you got it, so you should "put the array" under the user input.
List<String> names = new ArrayList<String>(); //<-- do the same for price(Integer) and product number (Integer)
public static void main(String args[]) throws Exception) {
//...
if(code==1) //<-- This was a l, check again your code.
{
System.out.print("") ;
System.out.print("Product number: ");
System.out.print("Product name: ");
String prodname = a.readLine();
names.add(prodname); //<-- add value to ArrayList
System.out.print("Price: ");
int price = Integer.parselnt(a.readLine());
System.out.println("");
}
//...
}
To print the array content you just need to iterate over the ArrayList:
for(String prodname: names)
System.out.println(prodname); //<-- This will print all your product names
public class DataInsideArrays {
public static DataInputStream a = new DataInputStream(System.in);
List<String> productname=new ArrayList<String>();
public static void main(String args[]) throws Exception {
// rest of your code...
if(code == 1) {
System.out.print("") ;
System.out.print("Product number: ");
System.out.print("Product name: ");
String prodname = a.readLine();
System.out.print("Price: ");
int price = Integer.parseInt(a.readLine());
System.out.println("");
////////////////////////to store data place arraylist here/////////////////////////////
productname.add(prod);
///////////////////// //same way use arr to store price and product no
} else if(code == 2) {
System.out.println("Display List of Products-Prices") ;
System.out.print("Enter product number:") ;
int prodnum=Integer.parseInt(a.readLine());
System.out.println("");
}
if(code == 3) {
System.out.println("Invalid");
System.out.println("Restart");
System.out.println("");
}
}
}
Here's the correct codes for the output I want. Maybe is there any other way I can get the same output of this with different coding?
import java.io.*;
import java.util.ArrayList;
public class DataArrays
{
public static DataInputStream a = new DataInputStream(System.in);
public static void main(String args[])throws Exception
{
ArrayList<Integer> prodNum = new ArrayList<Integer>(100);
ArrayList<String> prodName = new ArrayList<String>(100);
ArrayList<Integer> prodPrice = new ArrayList<Integer>(100);
ArrayList<Integer> prodPay = new ArrayList<Integer>(100);
for(int x=1;x<=100;x++)
{
System.out.println("1 - Maintenance");
System.out.println("2 - Transaction");
System.out.println("");
System.out.print("Enter code: ");
int code = Integer.parseInt(a.readLine());
System.out.println("");
int y = 1;
if(code==1)
{
System.out.print("") ;
System.out.println("Product number: "+ x);
prodNum.add(x); //this brings 1st input to array element #0 which is not needed
prodNum.add(x);
System.out.print("Product name: ");
String prodname = a.readLine();
prodName.add(prodname); //this brings 1st input to array element #0 which is not needed
prodName.add(prodname);
System.out.print("Price: ");
int prodprice = Integer.parseInt(a.readLine());
prodPrice.add(prodprice); //this brings 1st input to array element #0 which is not needed
prodPrice.add(prodprice);
System.out.print("Payment: ");
int prodpay = Integer.parseInt(a.readLine());
prodPay.add(prodpay); //this brings 1st input to array element #0 which is not needed
prodPay.add(prodpay);
System.out.println("");
System.out.println("Start New Transaction:");
System.out.println("");
}
else if(code==2)
{
System.out.println("Display List of Products-Prices");
System.out.print("Enter product number: ");
int i = Integer.parseInt(a.readLine());
i = prodNum.get(i); //this gets the data stored in the arraylist. Assuming it starts with 1 and above
prodNum.set(1, i);
System.out.println("");
System.out.println("Product name: "+ prodName.get(i));
System.out.println("Product price: "+ prodPrice.get(i));
System.out.println("Product payment: "+ prodPay.get(i));
System.out.println("");
System.out.println("Start New Transaction:");
}
else if(code>=3)
{
System.out.println("Invalid");
System.out.println("Restart");
System.out.println("");
}
else if(code==0)
{
System.out.println("Program will end");
break;
}}}}
Thank for helping me guys. Really appreciated it.

Need to call a method from a specific class

I need to call the method getAmount() from the Service class only. I do not want to add the values of the Purchaser class. Is there a way I can call the method explicitly from the Service class? I have put a ** where I am referring to.
package prog24178.assignment;
import java.util.Scanner;
public class Assignment3 {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
final int MAX = 99999; // Max array size.
Customer [] cust = new Customer[MAX];
int choice = 0;
int cnt = 0;
double total = 0;
//loop to choose customer type and create a new object.
for(cnt=0; cnt < MAX && (choice == 1 || choice ==2 || choice == 0); cnt++){
System.out.println("For a Service customer type 1, for a Purchaser type 2, to terminate the program press any number besides 1 or 2");
choice = s.nextInt();
switch (choice){
case 1:
cust [cnt] = new Service();
break;
case 2:
cust [cnt] = new Purchaser();
break;
default:
break;
}
}
//loop to print the entries
for(int i=0; i < cnt; i++){
if(cust[i]!= null)
cust[i].showData();
}
//loop to print the total for the service objects.**THIS IS LOOP I AM //REFFERING TO
for(int i=0; i < cnt; i++ ){
if(cust[i]!= null)
total = cust[i].getAmounts() + total;
}
System.out.println("Monthly invoice total: " + total);
s.close();
}
}
interface Functions {
public void getData();
public void showData();
public double getAmounts();
}
abstract class Customer implements Functions {
protected String name;
}
class Purchaser extends Customer {
protected double payment;
public Purchaser(){
getData();
}
public void getData() {
Scanner s = new Scanner(System.in);
System.out.println("Enter the name of the customer");
name = s.nextLine();
System.out.println("Enter payment amount: ");
payment = s.nextDouble();
}
public void showData() {
System.out.printf("Customer name: %s Payment amount is: %.2f\n",name,payment);
}
//**I DO NOT WANT TO CALL THIS METHOD
public double getAmounts(){
return this.payment;
}
}
class Service extends Customer {
protected String date;
public double amount;
public Service () {
getData();
}
public void getData() {
Scanner s = new Scanner(System.in);
System.out.println("Enter the name of the customer");
name = s.nextLine();
System.out.println("Enter date of Service: ");
date = s.nextLine();
System.out.println("Enter the cost of Service: ");
amount = s.nextDouble();
}
public void showData() {
System.out.printf("Customer name: %s The date is: %s, the Amount owed is: %.2f\n",name, date, amount);
}
//**THIS IS THE METHOD I NEED TO CALL
public double getAmounts(){
return this.amount;
}
}
Check your customer for type:
if (cust[i] instanceof Service) {
total = cust[i].getAmounts() + total;
}
That takes care of the null check automatically as well.

binarySearch errors in Java

I have a BankAccount class that models bank account information and a main method that is supposed to create an array list of BankAccount objects from user input and then write that info to a text file.
Here's my BankAccount class:
package BankAccount;
public class BankAccount implements Comparable<BankAccount> {
String accountNumber;
String firstName, lastName;
char middleInitial;
double balance;
public static double OVERDRAFT_FEE = 26.00;
public BankAccount(String acno, String fName, char midInit, String lName, double initBal){
acno = accountNumber;
fName = firstName;
midInit = middleInitial;
lName = lastName;
initBal = balance;
}
public String getAccountNumber(){
return accountNumber;
}
public String getFirstName(){
return firstName;
}
public char getMiddleInitial(){
return middleInitial;
}
public String getLastName(){
return lastName;
}
public double getBalance(){
return balance;
}
public void deposit(double amount){
if (amount > 0)
balance = balance + amount;
else
throw new IllegalArgumentException("deposit(double amount): Amount cannot be less than 0.");
}
public void withdraw(double amount){
if (balance >= amount && amount > 0)
balance = balance - amount;
else if(balance < amount && amount > 0)
balance = balance - amount - OVERDRAFT_FEE;
else
throw new IllegalArgumentException("withdraw(double amount): Amount cannot be less than 0.");
}
#Override
public int compareTo(BankAccount another){
if (Integer.parseInt(this.getAccountNumber()) > Integer.parseInt(another.getAccountNumber()))
return 1;
else if(Integer.parseInt(this.getAccountNumber()) < Integer.parseInt(another.getAccountNumber()))
return -1;
else
return 0;
}
}
My main method looks like this:
public class GeauxBank
{
public static void main(String[] args)
{
ArrayList<BankAccount> accounts = new ArrayList<BankAccount>();
Scanner keyb = new Scanner(System.in);
// write code to read data from acinfo.dbf. Be sure to handle
// FileNotFoundException in a try-catch statement. You don't
// need to do anything in the catch block.
int option;
String acno;
String fName;
char midInit;
String lName;
double initBal=0,amount;
int pos;
do
{
menu();
System.out.println();
System.out.print("Select an option->");
option = keyb.nextInt();
System.out.println();
switch(option)
{
case 1:
System.out.print("Enter a 10-character long account number->");
acno = keyb.next();
System.out.print("Customer's first name ->");
fName = keyb.next();
System.out.print("Customer's middle initial ->");
midInit = keyb.next().charAt(0);
System.out.print("Customer's last name ->");
lName = keyb.next();
System.out.print("Initial Deposit ->");
initBal = keyb.nextDouble();
Collections.sort(accounts);
pos = binarySearch(accounts,acno);
if (pos < 0)
{
try
{
accounts.add(new BankAccount(acno,fName,midInit,lName,initBal));
Collections.sort(accounts);
}
catch(IllegalArgumentException e)
{
System.out.println(e);
}
}
else
System.out.println(acno+" has already being asssigned another customer");
break;
case 2:
System.out.println("Enter the 10-character long account number of the account you wish to close->");
acno = keyb.next();
pos = binarySearch(accounts, acno);
accounts.remove(pos);
break;
case 3:
System.out.println("Enter the 10-character long account number->");
acno = keyb.next();
System.out.println("Enter the amount you wish to deposit->");
amount = keyb.nextDouble();
pos = binarySearch(accounts, acno);
accounts.get(pos).deposit(amount);
break;
case 4:
System.out.println("Enter the 10-character long account number->");
acno = keyb.next();
System.out.println("Enter the amount you wish to withdraw->");
amount = keyb.nextDouble();
accounts.get(binarySearch(accounts, acno)).withdraw(amount);
break;
case 5:
System.out.println("Enter the 10-character long account number->");
acno = keyb.next();
accounts.get(binarySearch(accounts, acno)).getBalance();
break;
case 6:
int i;
int length = accounts.size();
for(i = 0; i < length; i++) {
System.out.print(accounts.get(i).getFirstName()+" ");
System.out.print(accounts.get(i).getMiddleInitial()+" ");
System.out.println(accounts.get(i).getLastName());
}
break;
case 0:
break;
default:
System.out.println("Invalid menu option");
}
}while (option != 0);
try{
PrintWriter writer = new PrintWriter("acinfo.dbf");
int i;
int length = accounts.size();
for(i = 0; i < length; i++){
writer.write(accounts.get(i)+"");
}
writer.close();
}
catch(FileNotFoundException f) {
System.out.println("The file acinfo.dbf does not exist.");
}
}
/**
* displays a text-based menu interface for this application
*/
public static void menu()
{
System.out.println();
System.out.println("G E A U X B A N K L O U I S I A N A L T D.");
System.out.println("=================================================");
System.out.println("[1]...............................open an account");
System.out.println("[2]..............................close an account");
System.out.println("[3].......................................deposit");
System.out.println("[4]....................................withdrawal");
System.out.println("[5]...............................balance inquiry");
System.out.println("[6].............................customers listing");
System.out.println("[0]..........................................exit");
System.out.println("=================================================");
}
/**
* searches an array list of BankAccount objects for a matching
* account number using the Binary Search algorithm.
* #param accounts an array list of BankAccount objects
* #param acno a string
* #return the index of the BankAccount object in the array list or
* with the account number that is the same as acno if such a BankAccount
* object can be found in the accounts array list; otherwise, the negative
* of the position the BankAccount object whose account number would
* have matched acno had it been found.
*/
public static int binarySearch(ArrayList<BankAccount> accounts, String acno)
{
int i;
int low,mid=0,high;
low = 0;
high = accounts.size()-1;
while (low <= high)
{
mid = (low+high)/2;
if (acno.compareTo(accounts.get(mid).getAccountNumber())==0)
return mid;
else if (acno.compareTo(accounts.get(mid).getAccountNumber())< 0)
high = mid-1;
else
low = mid+1;
}
return -1-mid;
}
}
I'm having problems with the binarySearch method. I can create one bank account just fine but when I try to create a second one, I get this message:
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.compareTo(String.java:1167)
at geauxbank.GeauxBank.binarySearch(GeauxBank.java:172)
at geauxbank.GeauxBank.main(GeauxBank.java:57)
Java Result: 1
It also gives me a similar message any time I try to use any other case in the switch statement that uses the binarySearch method. I don't know why this is. Also, when I try to write the information to a text file, I get this in the text file: BankAccount.BankAccount#1b67f74
or this: null null
I really don't know what is causing these problems. Any insight and clarity would be appreciated.
Your assignments are the wrong way around.
This takes the parameter and overwrites it with the fields which is null. The fields is left as null and you get an NPE when you attempt to dereference it.
acno = accountNumber;
try
accountNumber = acno;
I suggest you make fields final (unless you need to be able to change them) and you won't have this problem.

Categories