1 // This program helps staff manage customers'
2 // orders and decide who should be given a ready dish.
3
4 import java.util.*;
5
6 // This class represents all orders of customers
7 class ListOrder {
8
9 // Data member
10 private int numDishes;
11 // All dishes which the restaurant offers
12 private String[] dishes;
13 // Each dish has a queue of customers who ordered this dish
14 // All such queues are put inside an ArrayList called dishQueues
15 private ArrayList<Queue<Integer>> dishQueues;
16
17 // Constructor
18 public ListOrder(int numDishes, Scanner sc) {
19 this.numDishes = numDishes;
20 dishes = new String[this.numDishes];
21 ArrayList<Queue<Integer>> dishQueues = new ArrayList<Queue<Integer>>();
22 for(int i=0;i<this.numDishes;i++) {
23 dishes[i] = new String(sc.nextLine());
24 dishQueues.add(new LinkedList<Integer>());
25 }
26 }
27
28 // Add new order to the list
29 public void addNewOrder(int dishID, int tag) {
30 dishQueues.get(dishID-1).offer(new Integer(tag));
31 }
32
33 // Process food when it is ready
34 // Return the customer who currently ordered for the dish
35 // if there is no customer order for this dish return -1
36 public int processReadyFood(int dishID) {
37 int ready=0;
38 if (dishQueues.get(dishID-1).peek() == null)
39 return -1;
40 else
41 ready = dishQueues.get(dishID-1).poll();
42
43 return ready;
44 }
45
46 // Get dish's name
47 public String getDishName(int dishID) {
48 return dishes[dishID-1];
49 }
50
51 }
52
53 public class QuickEat {
54
55 public static void main(String [] args) {
56
57 Scanner sc = new Scanner(System.in);
58 int numDishes = sc.nextInt();
59 String command;
60 sc.nextLine();
61
62 // Create the list order of food
63 ListOrder listOrder = new ListOrder(numDishes, sc);
64
65 int noOfCommands = sc.nextInt();
66 sc.nextLine();
67
68 // Process commands
69 for(int i=0; i<noOfCommands;i++) {
70 command = sc.next();
71 if(command.equals("Order")) {
72 int tag = sc.nextInt();
73 int numOfDishes = sc.nextInt();
74 for(i=0;i<numOfDishes;i++)
75 listOrder.addNewOrder(sc.nextInt(),tag);
76 }
77 else if(command.equals("Ready")) {
78 int dishID = sc.nextInt();
79 int customer = listOrder.processReadyFood(dishID);
80 if(customer == -1)
81 System.out.println("Throw away " + listOrder.getDishName(dishID));
82 else
83 System.out.println(listOrder.getDishName(dishID) + " ready to be served to Tag " + customer);
84 }
85 }
86 }
87 }
我对代码的其他部分没有太大问题,但如果有,请向我强调!我得到的主要问题是当我进入
时3
Fish n Chips
Chicken Chop
Grilled Salmon
9
Order 1 2 1 3
我收到此错误。
Exception in thread "main" java.lang.NullPointerException
at ListOrder.addNewOrder(QuickEat.java:30)
at QuickEat.main(QuickEat.java:75)
我已经检查过了dishID-1但是提供方法没什么问题,但我还是不知道问题是什么! :((((HELP!:(
答案 0 :(得分:0)
您已创建private ArrayList<Queue<Integer>> dishQueues;
的引用,但尚未创建对象
这样做private ArrayList<Queue<Integer>> dishQueues=new ArrayList<Queue<Integer>> ;
答案 1 :(得分:0)
dishQueues
是null
。像这样初始化列表
private ArrayList<Queue<Integer>> dishQueues = new ArrayList<Queue<Integer>>();
问题更新后,现在问题应该是
dishQueues.get(dishID-1)
为null
更改addNewOrder
方法代码以检查null
并初始化新的队列实例(如果不存在)
public void addNewOrder(int dishID, int tag) {
if(dishQueues.get(dishID-1) == null)
dishQueues.get(dishID-1) = new LinkedList<Integer>();
dishQueues.get(dishID-1).offer(new Integer(tag));
}
您刚刚创建了一个包含队列对象的ArrayList
实例。我没有看到任何Queue
个实例的创建或对Queue
个实例的任何引用都要添加到列表中。因此,为列表中的每个索引创建实现Queue
的任何类的新/引用实例。否则,null
会导致 NPE
更新2
今天早上再次看到你的问题时,我看到构造函数中有成员变量阴影。
ArrayList<Queue<Integer>> dishQueues = new ArrayList<Queue<Integer>>();
。您正在创建一个局部变量,该变量仅在构造函数中具有作用域,而该构造函数不是成员变量。使用this
始终表示实例成员。这将有助于维护代码并提高可读性。您需要像这样更改构造函数
// Constructor
18 public ListOrder(int numDishes, Scanner sc) {
19 this.numDishes = numDishes;
20 dishes = new String[this.numDishes];
//this will initialize the member variable `dishQueues` in ListOrder
21 this.dishQueues = new ArrayList<Queue<Integer>>();
22 for(int i=0;i<this.numDishes;i++) {
23 dishes[i] = new String(sc.nextLine());
24 dishQueues.add(new LinkedList<Integer>());
25 }
26 }
希望你现在明白了!