【问题标题】:NullPointerException in linkedlist链表中的 NullPointerException
【发布时间】:2014-03-17 15:18:13
【问题描述】:
  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没有问题,但是offer方法,但我还是不知道是什么问题!!!! :((((帮助!:(

【问题讨论】:

  • 唯一可能的解释是dishQueuesnulldishQueues.get(dishID-1) 返回null。看代码是前者
  • 哦,是的,有道理,我该如何初始化它,或者至少让它不为空。
  • 阅读下面@Octopus 的回答
  • 是的,我知道,但是我如何在 > 的数组列表中实例化队列,因为它是抽象的?
  • 使用 JavaDocs 中的具体实现列表之一 - docs.oracle.com/javase/6/docs/api/java/util/Queue.html

标签: java nullpointerexception linked-list queue


【解决方案1】:

你已经创建了private ArrayList&lt;Queue&lt;Integer&gt;&gt; dishQueues;的引用,但是你还没有创建一个对象

这样做private ArrayList&lt;Queue&lt;Integer&gt;&gt; dishQueues=new ArrayList&lt;Queue&lt;Integer&gt;&gt; ;

【讨论】:

  • 对不起,我更正了我的代码。让我纠正我的问题
  • @user3274993 在第 21 行中,您已经初始化了 discQueues,但这是针对 Listorder() 的,您还必须为 addNewOrder() 重新初始化
【解决方案2】:

dishQueuesnull。像这样初始化列表

private ArrayList&lt;Queue&lt;Integer&gt;&gt; dishQueues = new ArrayList&lt;Queue&lt;Integer&gt;&gt;();

在您更新问题后,问题应该出现在

dishQueues.get(dishID-1)null

更改您的 addNewOrder 方法代码以检查 null 并在不存在时初始化新的 Queue 实例

     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&lt;Queue&lt;Integer&gt;&gt; dishQueues = new ArrayList&lt;Queue&lt;Integer&gt;&gt;();。您正在创建一个仅在构造函数中具有作用域的局部变量,它不是成员变量。始终使用 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     }

希望你现在明白了!

【讨论】:

  • 我更正了我的代码,但我没有在问题中更新它。谢谢兄弟,但这不是我要处理的主要问题:(
  • 我已经更新了答案。你能试试吗?我要离开这一天。问题应该主要是它。尝试调试代码,您可以轻松修复这些错误。
  • 现在正在尝试。我遇到了一些错误。 discQueues.get(dishID-1) 在您的回答中被声明为我认为不正确的变量
  • 好吧,现在说得通了。现在我在尝试创建实例时遇到了麻烦。哈哈:((((
  • Queue 是一个接口,不能如图所示实例化。您应该使用 JavaDocs 中列出的具体实现之一 - docs.oracle.com/javase/6/docs/api/java/util/Queue.html
猜你喜欢
  • 2015-03-30
  • 2017-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-28
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
相关资源
最近更新 更多