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

Java简易票务模拟器非顺序出票报错问题排查

问题背景

正在开发简易票务模拟程序:

  • 定义Seats类,使用静态LinkedList存储放映厅全部座位
  • 共50个座位,每10个为一排,对应排号a到e,1-10为a排、11-20为b排,以此类推
  • 出票逻辑为:用户输入排号+座位号,匹配到对应可用座位后从列表中移除,避免重复预订
  • 测试时发现仅按a1、a2、a3……的顺序出票能正常运行,非顺序出票(例如买完a1-a4后买b11)会误判座位已被出票,怀疑LinkedList要求必须按顺序操作。

原代码如下:
Seats类:

public class Seats {

    public static LinkedList<Seats> seatsInSaloon;
    private final int seatNumber;
    private final char seatChar;

    public Seats(int seatNumber, char seatChar) {
        this.seatChar = seatChar;
        this.seatNumber = seatNumber;
    }

    private static void generateSeats() {
        seatsInSaloon = new LinkedList<Seats>();
        char x = 'a';
        for (int i = 1; i < 51; i++) {
            if (i % 10 == 0) {
                Seats seats = new Seats(i, x);
                seatsInSaloon.add(seats);
                x++;
            } else {
                Seats seats = new Seats(i, x);
                seatsInSaloon.add(seats);
            }
        }
    }

    public int getSeatNumber() {
        return seatNumber;
    }

    public char getSeatChar() {
        return seatChar;
    }

    public static void fillSeats() {
        generateSeats();
    }
}

Ticketing类:

public class Ticketing {
    private static Seats seats;

    public static LinkedList<Seats> seeAllSeatsAvailable() {
        return Seats.seatsInSaloon;
    }

    public static void ticketSeat(int seatNum, char seatChar) {
        if ((seatNum > 50 || seatNum < 1) || (seatChar > 'e' || seatChar < 'a')) {
            System.out.println("please check the numbers you have entered .... ");
        }

        for (Seats s : Seats.seatsInSaloon) {
            if (s.getSeatChar() == seatChar && s.getSeatNumber() == seatNum) {
                System.out.println("HERE IS YOUR TICKET : " + seatChar + seatNum);
                Seats.seatsInSaloon.remove(s);
                break;
            } else if (!Seats.seatsInSaloon.contains(s.getSeatChar() == seatChar && s.getSeatNumber() == seatNum)) {
                System.out.println("sorry... This ticket has already been issued");
                break;
            }
        }
    }
}

测试代码:

public class TicketDriver {
    public static void main(String[] args) {
        Seats.fillSeats();

        Ticketing.ticketSeat(1, 'a'); //正常
        Ticketing.ticketSeat(2, 'a'); //正常
        Ticketing.ticketSeat(3, 'a'); //正常
        Ticketing.ticketSeat(4, 'a'); //正常
        Ticketing.ticketSeat(4, 'a'); //正常,提示已出票
        Ticketing.ticketSeat(11, 'b'); //误报已出票
    }
}
问题原因

这个问题和LinkedList数据结构本身无关,完全是ticketSeat方法的逻辑错误导致的,共有3处核心问题:

  1. 遍历判断逻辑完全错误:for循环逐个遍历列表元素时,只要第一个元素不匹配目标座位,就会进入else if分支,直接打印错误提示并break终止遍历,根本不会访问列表后续的元素。顺序买a1-a4时,这几个座位刚好在列表最前端,第一个元素就能匹配成功,所以不会触发问题;买b11时,列表第一个元素是a5,和目标不匹配,直接就走错误分支了。
  2. contains方法使用错误:List.contains()方法的参数是要查找的列表元素,传入的布尔表达式(运算结果是true/false)和列表存储的Seats类型完全不匹配,因此这个判断永远返回false,取反后永远为true,只要第一个元素不匹配就必然触发错误提示。
  3. 参数校验缺少返回逻辑:判断输入参数非法后,没有执行return终止方法,就算输入不符合要求,代码还是会继续往下执行遍历逻辑。

另外Seats类的generateSeats方法中if和else分支的添加座位逻辑完全重复,属于冗余代码,不影响功能但可以简化。

修复方案

调整ticketSeat方法的执行逻辑:

  • 参数校验不通过时直接返回,不执行后续逻辑
  • 遍历整个可用座位列表查找匹配项,找到后打印出票信息、移除座位,直接终止方法
  • 完整遍历完列表都没找到匹配座位时,才提示座位已被出票
    修正后的代码如下:
public static void ticketSeat(int seatNum, char seatChar) {
    // 参数非法直接终止方法
    if ((seatNum > 50 || seatNum < 1) || (seatChar > 'e' || seatChar < 'a')) {
        System.out.println("please check the numbers you have entered .... ");
        return;
    }

    // 遍历所有可用座位查找匹配项
    for (Seats s : Seats.seatsInSaloon) {
        if (s.getSeatChar() == seatChar && s.getSeatNumber() == seatNum) {
            System.out.println("HERE IS YOUR TICKET : " + seatChar + seatNum);
            Seats.seatsInSaloon.remove(s);
            return;
        }
    }

    // 遍历完未找到匹配项,说明座位已出票
    System.out.println("sorry... This ticket has already been issued");
}

注:for-each遍历过程中直接调用List的remove方法会触发并发修改异常,当前代码因为移除元素后直接return不会继续迭代,所以暂时不会触发问题,如果后续需要扩展逻辑,建议使用Iterator的remove方法执行删除操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:57:24