我看了一下这个线程中的代码:https://codereview.stackexchange.com/questions/98105/priority-stack-in-java
这使用对象和优先级实现了一个PriorityStack。我需要一个实现,其中您只将对象添加到PriorityStack,并使用Comparable接口定义哪个属性应该优先化。
例如:
我有一张狗的名单:
- 姓名="跳过",年龄= 4
- 姓名="格雷戈里",年龄= 3岁
- 姓名="吉吉",年龄= 4岁
在Dog对象中,我将使用以下代码实现Comparable接口:
public int compareTo(Dog other) {
if(other == null) {
return -1;
}
return this.age - other.age;
}
我如何使用它来确定我的PriorityStack的优先级?
这样做的结果应该是最小的狗第一,然后其他2狗基于先进后出
2条答案
按热度按时间ruyhziif1#
我们可以把栈看作是一个优先级队列,它根据项目排队的时间来确定优先级,虽然它没有我们通常所说的栈那么高效,但它是LIFO。
用
PriorityQueue
可以更容易地实现PriorityStack
,而且可能效率更高。唯一的问题是,你要么需要在Dog
类中添加一个time
字段,要么将Dog
对象 Package 在另一个具有time
字段的类中。我倾向于后者:我们称之为PQDog
,当然你需要一个自定义的比较器。time
字段不必是某个项目入队的实际时间。如果您确保为每个入队的项目递增它,它可以是一个整数。前提是您不打算在队列的生命周期中入队超过20亿个项目。请考虑一下,如果您从Integer.MinValue
开始序列(或者不管它在Java中叫什么),你可以把这个范围扩展到40亿。我们的想法是定义类:
我不是一个真正的Java程序员,所以不要指望下面的代码编译起来没有问题,但我认为它足以给你指明正确的方向。
当你想把一个
Dog
放到队列中时,你把它 Package 在一个PQDog
对象中,并添加新的序列号,假设你有一个名为QueueSequence
的静态变量,你每次排队前都会递增它。当然,当您从队列中取出
pop
时,您必须打开Dog
。看起来你的排序要求是“按年龄升序和时间降序”。所以你的比较器应该是这样的:
或者,如果
Dog
类已经有了一个按年龄进行比较的CompareTo
,则可以将上面的代码更改为:在我看来,当您可以使用标准的Java
PriorityQueue
、一个定制比较器和几行接口代码来解决问题时,引入一个不完整且未经审查的定制PriorityStack
数据结构似乎很愚蠢。顺便说一句,通常不应该在
Comparable
中使用return a - b
,想象一下当a
等于最小整数时会发生什么(或者说是足够大的负数)并且b
是一个足够大的正数。(实际上是下溢,但同样的事情)抬起它丑陋的头。结果将是一个正数,错误地指示a
大于b
。是的,我知道在这个特殊的案例中你不会遇到这个问题。至少,我不认为你有任何狗是负20亿岁。但我们作为程序员所做的很多事情都依赖于模式和惯例。一个人应该养成在可行的情况下编写防弹代码的习惯。谁也不知道别人会在你写完代码后用你的代码做什么。也许某个初学者正在寻找
Comparable
的实现,运行你的代码,把它复制到他的程序中,所有的单元测试和集成测试都通过了,代码进入了生产环境,四个月后有些东西坏了。不是我凭经验说的......
ecbunoof2#
(在评论中作出澄清后编辑的答复)
在链接的PriorityStack中,它获取两个值并将它们存储在TreeMap中。在您的示例中,一旦您使Dog类具有可比性(并且Dog对象包含
.age
属性),则可以将这些Dog对象存储在TreeSet中(这是一个排序的集合,根据Dog中的compareTo()方法排序)。您可以将TreeSet示例化为
TreeSet<Dog> stack = new TreeSet<>();