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.
相关产品推荐
相关产品推荐

