I have created two classes, Cashier and OrderList.
I need to add new orders (which are made up of the cashiers name, the order number and the time the order was placed) to an arraylist created in the OrderList class.
Eventually I will add a cook class which will remove orders from the orderList, so the same arrayList must be available to both the cashier and class ( Not sure how to do this - at the moment I create a new OrderList object in the Cashier class , I don't think this is correct but one thing at a time)
The problem I am getting, is that when I try and add a new order to the arrayList, I get an error:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
Exception in thread "Thread-5" java.lang.NullPointerException
So I am not successfully adding orders to the arrayList.
Any help would be much appreciated!
Cashier class:
public class Cashier implements Runnable{
String theCashier;
private static int theNextNum = 0;
private String orderNo;
private String timeNow;
private String stringOrder;
public OrderList a;
public void setCashier(String aCashier) // set Cashier name
{
theCashier = aCashier;
}
public String getOrderNo()
{
return orderNo;
}
public synchronized String uniqueNumber() // next Order number
{
theNextNum ++;
int order = theNextNum;
orderNo = String.valueOf(order);
return orderNo;
}
public String formatOrd()
{
stringOrder = orderNo + theCashier + timeNow;
return stringOrder;
}
public String now() // get the current time
{
String DATE_FORMAT_NOW = "HH:mm:ss";
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
String time = sdf.format(cal.getTime());
timeNow = time;
return timeNow;
}
}
public void run()
{
out.println("Cashier " + theCashier + " added order: " );
out.println(orderNo + " at " + timeNow);
a.listOfOrders.add(stringOrder);
}
public static void main (String args[])
{
Cashier c = new Cashier();
c.setCashier("Bob");
c.now();
c.uniqueNumber();
c.formatOrd();
new Thread©.start();
}
}
OrderList class:
public class OrderList implements Runnable
{
ArrayList<String> listOfOrders = new ArrayList<String>();
public void addOrder(String s)
{
listOfOrders.add(s);
}
public void run()
{
}
}
arrayList help
Started by needHelp0611, Oct 13 2010 04:59 AM
5 replies to this topic
#1
Posted 13 October 2010 - 04:59 AM
|
|
|
#2
Posted 13 October 2010 - 05:42 AM
you don't create an orderList isntance, add
Also you close 1 "}" too many in front of the "public void run" method
public Cashier() {
a = new OrderList();
}
to the cashier class.Also you close 1 "}" too many in front of the "public void run" method
#3
Posted 13 October 2010 - 05:46 AM
If I create a new orderList object , can I use this same arrayList in that object in the Cook class that I am going to create?
Many Thanks.
Many Thanks.
#4
Posted 13 October 2010 - 06:32 AM
WALL OF TEXT INCOMING
You'll have to pass the orderlist to the cook.
In the main you can do like
Generally, if you need the list at the cook. You either place the whole list in the Cook class, and manage it there. If that's not possible because other classes need the list too, you put the list elsewhere, and every time you need something from it, you ask the class where the list is to pass you the list. you then use the list and throw it away again. IF you need it again, you ask it again. This keeps the info you get up to date.
The following is how I interpret it, and would do it.
I'm sorry to say, but the whole design of your classes looks... odd. To start, the Cashier class actually looks more like an order than a cashier. It has the orderNo, it has the order itself, the time of the order, and who wrote the order.
I would rename it to order, and rename formatOrd into "toString".
Tostring causes the method to be automatically called if you do System.out.println(order);
Also, prepare, i would remove
Why do it this way? Generally, in Object oriented programming, you don't want your objects to be in a surreal state. Imagine if you had the "Person" class which has a "String name"
You don't want to make an empty constructor to create a Person and then call person.setName() to give it a name. BEcause that makes it possible for your application to have persons with no names, which makes no sence.
oh, i also let the constructor fill in the order.
So for this order, it wouldn't make sence if it had no time, orderNo, or it has no author(cashier) -> in constructor.
Now if you needed more info of the Cashier. Then create a new class Cashier, give it all the attributes it needs, and instead of having String theCashier, you do Cashier theCashier in the Order class.
In the end i got something like:
The cook will cook once every 4seconds (Thread.sleep(4000); )
In the main method i did:
while(true){
String line = scanner.nextLine();
cook.addOrder(new Order("Bob", line));
}
Which allows you to add orders to the orderlist for the cook at runtime, just type what you want, and upon <Enter> it will be given to the cook.
I'm sorry if this is a bit overwhelming. Feel free to ask anything you want.
You'll have to pass the orderlist to the cook.
In the main you can do like
Cook cook = new Cook(c.getOrderList() );This won't keep track of new orders that are added after the cook is made tho.
Generally, if you need the list at the cook. You either place the whole list in the Cook class, and manage it there. If that's not possible because other classes need the list too, you put the list elsewhere, and every time you need something from it, you ask the class where the list is to pass you the list. you then use the list and throw it away again. IF you need it again, you ask it again. This keeps the info you get up to date.
public class IgotTheList{
private List<String> list;
public List<String> getList(){
return list;
}
}
public class IneedTheList{
IgotTheList heHasTheList;
public void someMethodWithWeirdName(){
List<String> myCopyOfTheList = heHasTheList.getList();
//mycopyofthelist can now be used
}
}
The following is how I interpret it, and would do it.
I'm sorry to say, but the whole design of your classes looks... odd. To start, the Cashier class actually looks more like an order than a cashier. It has the orderNo, it has the order itself, the time of the order, and who wrote the order.
I would rename it to order, and rename formatOrd into "toString".
Tostring causes the method to be automatically called if you do System.out.println(order);
Also, prepare, i would remove
- public synchronized String uniqueNumber()
- public void setCashier(String aCashier)
- public String now()
public Order(String theCashier, String order) {
this.theCashier = theCashier;
String DATE_FORMAT_NOW = "HH:mm:ss";
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
String time = sdf.format(cal.getTime());
timeNow = time;
orderNo = ++theNextNum;
stringOrder = order;
}
This constructor basicly does the setCashier, and now(), and uniqueNumber().Why do it this way? Generally, in Object oriented programming, you don't want your objects to be in a surreal state. Imagine if you had the "Person" class which has a "String name"
You don't want to make an empty constructor to create a Person and then call person.setName() to give it a name. BEcause that makes it possible for your application to have persons with no names, which makes no sence.
oh, i also let the constructor fill in the order.
So for this order, it wouldn't make sence if it had no time, orderNo, or it has no author(cashier) -> in constructor.
Now if you needed more info of the Cashier. Then create a new class Cashier, give it all the attributes it needs, and instead of having String theCashier, you do Cashier theCashier in the Order class.
In the end i got something like:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Scanner;
/**
*
* @author Wim
*/
public class Order {
private static int theNextNum = 0;
String theCashier;
private int orderNo;
private String timeNow;
private String stringOrder;
public Order(String theCashier, String order) {
this.theCashier = theCashier;
String DATE_FORMAT_NOW = "HH:mm:ss";
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
String time = sdf.format(cal.getTime());
timeNow = time;
orderNo = ++theNextNum;
stringOrder = order;
}
public String getTheCashier() {
return theCashier;
}
public void setOrder(String order){
stringOrder+=order + "";
}
public int getOrderNo() {
return orderNo;
}
public String toString() {
return orderNo + ": Cashier" + theCashier + " - " + timeNow + "\n" +
"Order: " + stringOrder;
}
public static void main(String[] args) {
Cook cook = new Cook();
cook.addOrder(new Order("Bob", "spaghetti"));
cook.addOrder(new Order("Bob", "salad"));
cook.addOrder(new Order("Bob", "burger"));
new Thread(cook).start();
Scanner scanner = new Scanner(System.in);
while(true){
String line = scanner.nextLine();
cook.addOrder(new Order("Bob", line));
}
}
}
and
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Wim
*/
public class Cook implements Runnable {
ArrayList<Order> listOfOrders = new ArrayList<Order>();
public void addOrder(Order o) {
listOfOrders.add(o);
}
public void cook() {
System.out.println("Cook is cooking the following order:\n" + listOfOrders.get(0));
System.out.println("");
listOfOrders.remove(0);
}
public void run() {
while (true) {
if (listOfOrders.size() > 0) {
cook();
}
try {
Thread.sleep(4000);
} catch (InterruptedException ex) {
Logger.getLogger(Cook.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
This main creates a cook, gives it 3 orders (spaghetti, salad, burger) and .start()s the cook.The cook will cook once every 4seconds (Thread.sleep(4000); )
In the main method i did:
while(true){
String line = scanner.nextLine();
cook.addOrder(new Order("Bob", line));
}
Which allows you to add orders to the orderlist for the cook at runtime, just type what you want, and upon <Enter> it will be given to the cook.
I'm sorry if this is a bit overwhelming. Feel free to ask anything you want.
#5
Posted 13 October 2010 - 07:34 AM
Thanks, that's a great help.
One more thing, I want to add a few second delay between each order being added to the listOfOrders, which is why I had Cashier implement runnable.
I have added this to the order class like below and made Order implement runnable etc, but it just has a 5 second delay before adding all orders to the list. Do I need a for loop or a while statement?
public void run()
{
try{
Thread.sleep(5000);
}
catch (Exception e)
{
}
cook.addOrder(a);
}
One more thing, I want to add a few second delay between each order being added to the listOfOrders, which is why I had Cashier implement runnable.
I have added this to the order class like below and made Order implement runnable etc, but it just has a 5 second delay before adding all orders to the list. Do I need a for loop or a while statement?
public void run()
{
try{
Thread.sleep(5000);
}
catch (Exception e)
{
}
cook.addOrder(a);
}
#6
Posted 13 October 2010 - 08:24 AM
You need a while(true) loop or something else.
The thread dies when the run() method is finished. To keep the thread alive, run must keep running.
Usually, a thread class has a "boolean run"
The thread dies when the run() method is finished. To keep the thread alive, run must keep running.
Usually, a thread class has a "boolean run"
private boolean run;
//other code
public void run()
{
run=true;
while(run){
try{
Thread.sleep(5000);
}
catch (Exception e)
{
}
cook.addOrder(a);
}
}
It's usually done this way because you can now make a method:
public void stopThread(){
run=false;
}


Sign In
Create Account

Back to top









