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

AnimalShelter的dequeueAny方法异常:先加猫时compareTo返回0

动物收容所dequeueAny方法BUG修复方案

问题根源

你的dequeueAny方法失效的核心原因是**dateArrived字段没有生成严格递增的唯一顺序值**,导致猫和狗队列队首的dateArrived相等,compareTo()返回0,触发三元表达式的默认分支(返回狗),从而违背了FIFO规则。

解决方案

改用全局递增序列号替代时间戳作为动物的入队顺序标识,彻底避免顺序值重复的问题。

1. 修正Animal基类及子类

public abstract class Animal {
    protected int sequence; // 用递增序列号记录入队顺序

    public int compareTo(Animal other) {
        return Integer.compare(this.sequence, other.sequence);
    }
}

public class Cat extends Animal {}
public class Dog extends Animal {}

2. 修正AnimalShelter类

添加全局计数器,入队时为每个动物分配唯一递增的序列号:

import java.util.LinkedList;
import java.util.Queue;

public class AnimalShelter {
    private Queue<Cat> cats = new LinkedList<>();
    private Queue<Dog> dogs = new LinkedList<>();
    private int sequenceCounter = 0; // 全局递增计数器

    public void enqueue(Animal animal) {
        // 入队时分配唯一序列号
        animal.sequence = sequenceCounter++;
        if (animal instanceof Cat) {
            cats.add((Cat) animal);
        } else if (animal instanceof Dog) {
            dogs.add((Dog) animal);
        }
    }

    public Animal dequeueAny() throws Exception {
        boolean noCat = cats.isEmpty();
        boolean noDog = dogs.isEmpty();

        if (noCat && noDog) {
            throw new Exception("There are no more animals!");
        }
        if (noCat) {
            return dogs.poll();
        } else if (noDog) {
            return cats.poll();
        } else {
            Cat firstCat = cats.peek();
            Dog firstDog = dogs.peek();
            // 比较序列号,严格按入队顺序出队
            return firstCat.sequence < firstDog.sequence ? cats.poll() : dogs.poll();
        }
    }

    // 实现其他必要方法
    public Cat dequeueCat() throws Exception {
        if (cats.isEmpty()) throw new Exception("No cats available!");
        return cats.poll();
    }

    public Dog dequeueDog() throws Exception {
        if (dogs.isEmpty()) throw new Exception("No dogs available!");
        return dogs.poll();
    }

    // 测试用的getter
    public Queue<Cat> getCats() { return cats; }
    public Queue<Dog> getDogs() { return dogs; }
}

3. 测试代码验证

import java.util.Arrays;
import java.util.List;

public class Test {
    public static void main(String[] args) throws Exception {
        AnimalShelter as = new AnimalShelter();
        List<Animal> animals = Arrays.asList(new Cat(), new Dog(), new Cat(), new Dog(), new Cat(),
                new Dog(), new Cat(), new Dog(), new Cat());

        for (Animal animal : animals) {
            as.enqueue(animal);
        }

        Cat firstCat = as.getCats().peek();
        Dog firstDog = as.getDogs().peek();
        System.out.println(firstCat.sequence); // 输出0(第一个入队的是猫)
        System.out.println(firstDog.sequence); // 输出1
        System.out.println(firstCat.compareTo(firstDog)); // 输出-1,正确

        Animal adopted = as.dequeueAny();
        System.out.println(adopted.getClass().getSimpleName()); // 输出Cat,符合FIFO
        System.out.println(as.getCats().size()); // 输出4
        System.out.println(as.getDogs().size()); // 输出4
    }
}

关键说明

  • 用全局计数器生成序列号,能保证每个动物的入队顺序唯一且严格递增,完全避免了时间戳可能出现的重复问题。
  • 原代码中dateArrived的问题本质是顺序标识不唯一,改用序列号后,dequeueAny能准确判断哪个动物先入队。

内容的提问来源于stack exchange,提问作者Dexter M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:45:29