You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ArrayDeque传值时出现NullPointerException异常的排查与解决

问题分析与解决方案:ArrayDeque抛出NullPointerException

问题场景

自定义输入测试(如输入25 1)时,代码输出符合预期(结果为13),但提交代码时抛出NullPointerException,异常栈指向distributeTicket方法。

相关代码

//{ Driver Code Starts
//Initial Template for Java

import java.io.*;
import java.util.*;

class GFG{
    public static void main(String args[]) throws IOException { 
        BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        int t = Integer.parseInt(in.readLine());
        while (t-- > 0) {
            String s[]=in.readLine().trim().split(" ");
            int n=Integer.parseInt(s[0]);
            int k=Integer.parseInt(s[1]);
            Solution ob=new Solution();
            out.println(ob.distributeTicket(n,k));
        }
        out.close();
    }
}
// } Driver Code Ends

//User function Template for Java
class Solution {
    public static int distributeTicket(int N,int K)
    {
        ArrayDeque<Integer> q = new ArrayDeque<>();
        for(int i=1;i<=N;i++){
            q.add(i);
        }
        
        while(true){
            if(K==1 && q.size()==2)
                return q.peekLast();//.intValue();
            
            if(q.size() > K){
                for(int i=1;i<=K;i++)
                    q.pollFirst();
                
                for(int i=1;i<=K;i++)
                    q.pollLast();
            }
            
            else
                return q.peekLast();//.intValue();
        }
    }
}

异常信息

Exception in thread "main" java.lang.NullPointerException
    at Solution.distributeTicket(File.java:48)
    at GFG.main(File.java:17)

问题根源

当N是2*K的整数倍时,经过几轮pollFirst和pollLast操作后,队列会被完全清空。此时进入else分支调用q.peekLast()会返回null,而方法声明返回int类型,Java会自动将Integer拆箱为int,null拆箱操作直接触发NullPointerException。

比如输入4 2时,队列初始为[1,2,3,4]:

  1. 执行pollFirst()两次,队列变为[3,4]
  2. 执行pollLast()两次,队列变为空
  3. 进入下一轮循环,q.size() > K不成立,进入else分支返回q.peekLast(),得到null,拆箱报错。

解决方案

调整循环逻辑,避免处理空队列的情况,同时记录每次取出的最后一个元素,确保队列清空时能直接返回正确结果。修改后的distributeTicket方法如下:

class Solution {
    public static int distributeTicket(int N,int K)
    {
        ArrayDeque<Integer> q = new ArrayDeque<>();
        for(int i=1;i<=N;i++){
            q.add(i);
        }
        
        int lastTicket = -1;
        while(true){
            // 从头部取K张票,记录最后取出的票
            for(int i=1;i<=K && !q.isEmpty();i++){
                lastTicket = q.pollFirst();
            }
            if(q.isEmpty()){
                return lastTicket;
            }
            
            // 从尾部取K张票,记录最后取出的票
            for(int i=1;i<=K && !q.isEmpty();i++){
                lastTicket = q.pollLast();
            }
            if(q.isEmpty()){
                return lastTicket;
            }
            
            // 剩余票数不足K张时,取完剩余所有票并返回最后一张
            if(q.size() <= K){
                while(!q.isEmpty()){
                    lastTicket = q.pollFirst();
                }
                return lastTicket;
            }
        }
    }
}

该方案通过以下方式避免空指针:

  • 每次取票时判断队列是否为空,为空则直接返回最后取出的票
  • 剩余票数不足K张时,直接取完所有剩余票并返回最后一张,确保不会出现空队列调用peekLast()的情况

内容的提问来源于stack exchange,提问作者user9342976

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:54:54