猫狗队列是一个很经典的问题了吧,在书上我也翻看了很久;而网上的答案呢,也是千篇一律的,跟书的代码也是一字不差的,几乎除了照搬似乎都没什么思路可言的,甚至连书上提到注意的点都没有…
一开始我是没什么思路的,翻来覆去研究书上,发现原来挺简单;但用思路写起来还真不是一回事,挺难的。各个问题涉及到的地方很多,就是如何解决的问题很多,特别是题目的第二点要求。
以下是我研究书好一会做题的过程,也发现书上一些不太好的问题吧,比如对装载 Pet 实例的类命名为:PetEnterQueue ,真的很容易造成误解以为是个队列;而且我觉得书中所写的这类似乎有些多余了,这并不是说他的实现方式不对,这样的实现思路也的确是要这样做的;但其实只要创建一个由猫和狗组合成的共同的类就好了,实现的方法写在其中也OK,以下是我的解题过程。
题目:宠物、狗、猫类代码如下
(此处代码太长,请点击阅读原文)
用户可以调用add() ,cat类或dog类的实例放入队列中
用户可以调用pollAll(),将队列中所有实例按照队列先后顺序依次弹出
用户可以调用pollDog()、pollCat(),将队列中dog类、cat类的实例按照进队列的先后顺序依次弹出
用户可以调用isEmpty(),检查队列中是否还有dog、cat的实例
用户可以调用isDogEmpty()、isCatEmpty(),分别检查队列中是否还有dog、cat的实例
思路:
1) 用户可以调用add() ,cat类或dog类的实例放入队列中
add() 也需要装载一个 Pet 的实例(多态),如何区分继承Pet类的 cat 和 dog 对象
123 | public Cat(){ super("cat");} |
由于Cat 和 Dog 的构造方法有 super("xxx")
这下可以用 equals 比较字符串区分不同的 cat 和 dog 对象,然后将符合条件的对象加入进 Cat 或 Dog 的队列中。
12345 | //最好避免魔法值,此中仅为示例boolean bool = pet.getPetType().equal("cat");if(bool){ add(pet);} |
2) 用户可以调用pollAll(),将队列中所有实例按照队列先后顺序依次弹出
按照依次按顺序弹出,根据类别的队列中的对象总数或队列的大小,来决定先那个队列使用 poll() 将所有对象出列。比如 Cat 队列的对象少于 Dog 队列,就将 Cat 队列先执行 poll() 。这里将 Cat 队列命名为 catQ,Dog 队列则为 dogQ
12345 | if(catQ.size() < dogQ.size()){ this.catQ.poll();}else{ this.dogQ.poll();} |
当然,在此之前还需要做一个非空的判断
123 | if (this.catQ.isEmpty() && this.dogQ.isEmpty()) { throw new RuntimeException("empty");} |
实现:
(此处代码太长,请点击阅读原文)
测试:
测试的话,在 maven 模块配置好 Junit4 再到 test 测试文件夹写好测试类,即可测验了
12345678910111213141516171819 | import com.pet.Pet;import com.pet.dc.queue.CatDogQueue;import org.junit.Test; public class JTest { } |
看了一个照搬书上还不错的例子,通过给定的类实现猫狗队列,他的 offer() 挺好的,如果队列已满再插入直接返回 false,不像add() 抛出异常中断执行 。异常尽早暴露原则的话,哦,那真是看情况而定了。
(全文完)
阅读原文