Hello guys,

I've been trying to finish a project. But I seem to be stuck.

I'm suppose to get the following output:

[1:18:10, 2:33:10, 3:21:10]
Remove customer:1:18:10
Remove customer:2:33:10
Remove customer:3:21:10
[Cashier:1001:0-0:Customer:null, Cashier:1002:0-0:Customer:null, Cashier:1003:0-
0:Customer:null, Cashier:1004:0-0:Customer:null]
Remove free cashier:Cashier:1001:0-0:Customer:null
Remove free cashier:Cashier:1002:0-0:Customer:null
Remove free cashier:Cashier:1003:0-0:Customer:null
Remove free cashier:Cashier:1004:0-0:Customer:null
[Cashier:1001:13-31:Customer:1:18:10, Cashier:1002:13-46:Customer:2:33:10, Cashi
er:1003:13-34:Customer:3:21:10, Cashier:1004:13-50:Customer:4:37:10]
Remove busy cashier:Cashier:1001:13-31:Customer:1:18:10
Remove busy cashier:Cashier:1003:13-34:Customer:3:21:10
Remove busy cashier:Cashier:1002:13-46:Customer:2:33:10
Remove busy cashier:Cashier:1004:13-50:Customer:4:37:10

But Instead, I'm only getting:

[1:18:10, 2:33:10, 3:21:10]
Remove customer:1:18:10
Remove customer:2:33:10
Remove customer:3:21:10
[]
Remove free cashier:null
Remove free cashier:null
Remove free cashier:null
Remove free cashier:null
Exception in thread "main" java.lang.NullPointerException
        at CheckoutArea.main(CheckoutArea.java:206)

I try to follow for the mistakes I have, and I can only conclude that I made a mistake in my constructor where I'm trying to creat Cashier objects and insert them into freeCashierQ

import java.util.*;
import java.util.Iterator;
import java.util.Queue;
import java.util.Deque;
import java.util.ArrayDeque;
import java.util.Arrays;

//--------------------------------------------------------------------------
//
// Define simulation queues in a checkout area. Queues hold references to Customer &
// Cashier objects
//
// Customer (FIFO) queue is used to hold waiting customers. If the queue is too long
// (i.e. >  customerQLimnit), customer goes away without entering customer queue
//
// There are several cashiers in a checkout area. Use PriorityQueue to 
// hold BUSY cashiers and FIFO queue to hold FREE cashiers, 
// i.e. a cashier that is FREE for the longest time should start be used first.
//
// To handle cashier in PriorityQueue, we need to define comparator 
// for comparing 2 cashier objects. Here is a constructor from Java API:
//
//  PriorityQueue(int initialCapacity, Comparator<? super E> comparator) 
//
// For priority queue, the default compare function is "natural ordering"
// i.e. for numbers, minimum value is returned first
//
// User can define own comparator class for PriorityQueue.
// For cashier objects, we like to have smallest end busy interval time first.
//
// The following class define compare() for two cashiers :

class CompareCashier implements Comparator<Cashier>{
    // overide compare() method
    public int compare(Cashier o1, Cashier o2) {
        return o1.getEndBusyIntervalTime() - o2.getEndBusyIntervalTime(); 
    }
}

// DO NOT ADD NEW METHODS OR DATA FIELDS
class CheckoutArea{

    // Private data fields:

    // define one priority queue 
    private PriorityQueue <Cashier> busyCashierQ;

    // define two FIFO queues
    private Queue<Customer> customerQ;
    private Queue<Cashier> freeCashierQ;

    // define customer queue limit
    private int customerQLimit;


    // Constructor 
    public CheckoutArea() 
    {
    }

    // Constructor 
    public CheckoutArea(int numCashiers, int customerQlimit, int startCashierID)
    {
        // use ArrayDeque to construct FIFO queue objects
        //ArrayDeque<Customer> adCust = new ArrayDeque<Customer>();
        //ArrayDeque<Cashier> adCash = new ArrayDeque<Cashier>();
        customerQ = new ArrayDeque<Customer>();
        freeCashierQ = new ArrayDeque<Cashier>();

        // construct PriorityQueue object
        // overide compare() in Comparator to compare Cashier objects
        busyCashierQ = new PriorityQueue<Cashier>( numCashiers, new CompareCashier()); 

        // initialize customerQlimit
        this.customerQLimit = customerQlimit;
        // Construct Cashier objects and insert into FreeCashierQ
        for (int i = startCashierID; i < numCashiers; i++) {
            freeCashierQ.add(new Cashier(i));
        }

        // add statements

    }

    public Cashier removeFreeCashierQ()
    {
        // remove and return a free cashier
        return freeCashierQ.poll();
    }

    public Cashier removeBusyCashierQ() 
    {
        // remove and return a busy cashier
        return busyCashierQ.poll();
    }

    public Customer removeCustomerQ()
    {
        // remove and return a customer 
        return customerQ.remove();
    }

    public void insertFreeCashierQ(Cashier cashier)
    {
        // insert a free cashier
        freeCashierQ.add(cashier);
    }

    public void insertBusyCashierQ(Cashier cashier)
    {
        // insert a busy cashier
        busyCashierQ.add(cashier);
    }

    public void insertCustomerQ(Customer customer)
    {
        // insert a customer 
        customerQ.add(customer);
    }

    public boolean emptyFreeCashierQ()
    {
        // is freeCashierQ empty?
        return freeCashierQ.isEmpty();
        //return false;
    }

    public boolean emptyBusyCashierQ()
    {
        // is busyCashierQ empty?
        return busyCashierQ.isEmpty();
    }

    public boolean emptyCustomerQ()
    {
        // is customerQ empty?
        return customerQ.isEmpty();
    }

    public int numFreeCashiers()
    {
        // get number of free cashiers
        return freeCashierQ.isEmpty() ? 0 : freeCashierQ.size(); 
    }

    public int numBusyCashiers()
    {
        // get number of busy cashiers
        return busyCashierQ.isEmpty() ? 0 : busyCashierQ.size(); 
    }

    public int numWaitingCustomers()
    {
        // get number of customers 
        return customerQ.isEmpty() ? 0 : customerQ.size(); 
    }

    public Cashier getFrontBusyCashierQ() 
    {
        // get front of busy cashiers
        // "retrieve" but not "remove"
        return busyCashierQ.peek();
    }

    public boolean isCustomerQTooLong()
    {
        // is customerQ too long?
        return !customerQ.isEmpty() && customerQ.size() >= customerQLimit; 
    }

    public void printStatistics()
    {
        System.out.println("\t# waiting customers  : "+numWaitingCustomers());
        System.out.println("\t# busy cashiers      : "+numBusyCashiers());
        System.out.println("\t# free cashiers      : "+numFreeCashiers());
    }

    public static void main(String[] args) {

        // quick check

        CheckoutArea sc = new CheckoutArea(4, 5, 1001);
        Customer c1 = new Customer(1,18,10);
        Customer c2 = new Customer(2,33,10);
        Customer c3 = new Customer(3,21,10);
        Customer c4 = new Customer(3,37,10);
        sc.insertCustomerQ(c1);
        sc.insertCustomerQ(c2);
        sc.insertCustomerQ(c3);
        System.out.println(""+sc.customerQ);
        System.out.println("Remove customer:"+sc.removeCustomerQ());
        System.out.println("Remove customer:"+sc.removeCustomerQ());
        System.out.println("Remove customer:"+sc.removeCustomerQ());

    System.out.println(""+sc.freeCashierQ);
        Cashier p1=sc.removeFreeCashierQ();
        Cashier p2=sc.removeFreeCashierQ();
        Cashier p3=sc.removeFreeCashierQ();
        Cashier p4=sc.removeFreeCashierQ();
        System.out.println("Remove free cashier:"+p1);
        System.out.println("Remove free cashier:"+p2);
        System.out.println("Remove free cashier:"+p3);
        System.out.println("Remove free cashier:"+p4);


    p1.freeToBusy (c1, 13);
    p2.freeToBusy (c2, 13);
    p3.freeToBusy (c3, 13);
    p4.freeToBusy (c4, 13);
    sc.insertBusyCashierQ(p1);
    sc.insertBusyCashierQ(p2);
    sc.insertBusyCashierQ(p3);
    sc.insertBusyCashierQ(p4);
    System.out.println(""+sc.busyCashierQ);
    p1=sc.removeBusyCashierQ();
    p2=sc.removeBusyCashierQ();
    p3=sc.removeBusyCashierQ();
    p4=sc.removeBusyCashierQ();
    System.out.println("Remove busy cashier:"+p1);
    System.out.println("Remove busy cashier:"+p2);
    System.out.println("Remove busy cashier:"+p3);
    System.out.println("Remove busy cashier:"+p4);

   }
};

followed is my Cashier.java file

// DO NOT ADD NEW METHODS OR DATA FIELDS!

class Cashier {

   // define constants for representing intervals
   static int BUSY = 1;
   static int FREE = 0;

   // cashier id and current customer which is served by this cashier 
   private int cashierID;
   private Customer currentCustomer; 

   // start time and end time of current interval
   private int startTime;
   private int endTime;

   // for keeping statistical data
   private int totalFreeTime;
   private int totalBusyTime;
   private int totalCustomers;

   // Constructor
   Cashier()
   {
        cashierID = -1;
        startTime = 0;
        endTime = 0;
        totalFreeTime = 0;
        totalBusyTime = 0;
        totalCustomers = 0; 
   }


   // Constructor with cashier id
   Cashier(int cashierId)
   {
        cashierID = cashierId;
        startTime = 0;
        endTime = 0;
        totalFreeTime = 0;
        totalBusyTime = 0;
        totalCustomers = 0;
   }

   // get data member methods 
   int getCashierID () 
   {
        return cashierID;
   }

   Customer getCustomer() 
   {
        return currentCustomer;
   }

   int getEndBusyIntervalTime() 
   {
        return endTime;
   }

   // functions for state transition
   // FREE -> BUSY :
   void freeToBusy (Customer currentCustomer, int currentTime)
   {
        // Main goal  : switch from free interval to busy interval
        //
        // end free interval, start busy interval
        // steps    : update totalFreeTime
        //          set startTime, endTime, currentCustomer, 
        //          update totalCustomers

        totalFreeTime += currentTime - startTime;
        BUSY = 1;
        this.currentCustomer = currentCustomer;
        startTime = currentTime;
        endTime = startTime + currentCustomer.getCheckoutTime();
        totalCustomers++;
   }

   // BUSY -> FREE :
   Customer busyToFree ()
   {
        // Main goal : switch from busy interval to free interval
        // 
        // steps     : update totalBusyTime 
        //         set startTime 
        //             return currentCustomer

        totalBusyTime += endTime - startTime;
        FREE = 0;
        startTime = endTime;
        this.currentCustomer = currentCustomer;

        return currentCustomer; 
   }

   // use this method at the end of simulation to update cashier data
   void setEndIntervalTime (int endsimulationtime, int intervalType)
   {
        // for end of simulation
        // set endTime, 
        // for FREE interval, update totalFreeTime
        // for BUSY interval, update totalBusyTime

        endTime = endsimulationtime;
        if (FREE == 1) {
            totalFreeTime += endTime - startTime;
        }else{
            totalBusyTime += endTime - startTime;
            this.currentCustomer = currentCustomer;
        }
   }

   // functions for printing statistics :
   void printStatistics () 
   {
    // print cashier statistics, see project statement

    System.out.println("\t\tCashier ID             : "+cashierID);
    System.out.println("\t\tTotal free time        : "+totalFreeTime);
    System.out.println("\t\tTotal busy time        : "+totalBusyTime);
    System.out.println("\t\tTotal # of customers   : "+totalCustomers);
    if (totalCustomers > 0)
        System.out.format("\t\tAverage checkout time  : %.2f%n\n",(totalBusyTime*1.0)/totalCustomers);
   }

    public String toString()
    {
        return "Cashier:"+cashierID+":"+startTime+"-"+endTime+":Customer:"+currentCustomer;
    }

    public static void main(String[] args) {
        // quick check
        Customer mycustomer = new Customer(20,30,40);
        Cashier mycashier = new Cashier(5);
        mycashier.freeToBusy (mycustomer, 13);
        System.out.println(mycashier);
   }
};

Exception in thread "main" java.lang.NullPointerException
at CheckoutArea.main(CheckoutArea.java:206)

What variable has a null value on line 206? When you find the variable, then backtrack in the code to find out why it does not have a valid non-null value.

You should add id strings to your println statements so you can find which println statement printed which line in the print out. For example:

System.out.println("freeCQ="+sc.freeCashierQ);

System.out.println("busyCQ="+sc.busyCashierQ);

Edited 4 Years Ago by NormR1

Thanks for the input, I will add string ID's.

Edited 4 Years Ago by ITOzann

Try debugging by adding more println statements to show the values of the variables and the contents of the queues as the code executes. The print outs will show you what the code is doing.

NormR1, I really appreciate your input. This is my first time taking Java and I find it really confusing. I just found the problem. By your post, I realize the Cashier objects were never initialize or created. After implementation, I got the right output.

Thanks a lot for the help! :)

Try to test more frequently. Type in a small amount of code with print out statements to show what it does. Compile and excute it to see if it is doing what you want. If so, comment out the print outs and add some more and do it again.

I'm actually working on it. Pretty much trying to add test statements for all the methods and constructors within the project file.

Try to test more frequently. Type in a small amount of code with print out statements to show what it does. Compile and excute it to see if it is doing what you want. If so, comment out the print outs and add some more and do it again.

This article has been dead for over six months. Start a new discussion instead.