具有复杂枚举的优先级队列?

发布于 2024-10-20 03:26:12 字数 798 浏览 1 评论 0原文

我正在用 Java 编写一个代理,它从程序中的各种其他对象接收对其服务的请求。限制是一次只能完成一个进程,这意味着 PriorityQueue 可能是表示对其服务的请求的最佳方式。

不幸的是,这些进程被存储为具有许多不同状态的枚举。有没有一种简单的方法可以编写比较器以按照我想要的方式对这些状态进行排序?也就是说,

public enum AgentProcess
{
    ACTION1, ACTION2, ACTION3, ACTION4, ACTION20
}

对于一些比较器,

public class ProcessComparator<Process>
{
    public int compare(Process a, Process b)
    {
        //some arbitrary ordering of the processes, e.g., ACTION3 > ACTION19 > ACTION4...
    }
}

我目前一直在做类似的事情,

public static int getValue(Process p)
{
    switch(p)
    case ACTION1:
         return 5;
    case ACTION2:
         return 29;
    case ACTION3:
         return 18;
    //etc
}

有没有一种方法可以重写我的枚举,使其自然排序,而不必为每个比较器定义权重或开关?

I am writing an Agent in Java that receives requests for its services from various other objects in the program. The restriction is that only one process can be done at once, which means that a PriorityQueue is probably the best way to represent requests for its services.

Unfortunately, these processes are stored as a enum with many different states. Is there an easy way to write a Comparator to order these states in the way I want? That is,

public enum AgentProcess
{
    ACTION1, ACTION2, ACTION3, ACTION4, ACTION20
}

with some Comparator

public class ProcessComparator<Process>
{
    public int compare(Process a, Process b)
    {
        //some arbitrary ordering of the processes, e.g., ACTION3 > ACTION19 > ACTION4...
    }
}

I'm currently stuck with doing something like

public static int getValue(Process p)
{
    switch(p)
    case ACTION1:
         return 5;
    case ACTION2:
         return 29;
    case ACTION3:
         return 18;
    //etc
}

Is there a way I could rewrite my enum so that it is naturally ordered, without having to define weights or a switch for each?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

屋檐 2024-10-27 03:26:12

我想到了三种解决方案:

  1. 按照需要的顺序指定枚举常量,并在比较器中使用 p.ordinal() 。
  2. 您指定排序索引作为枚举常量的参数,例如ACTION1(3)、ACTION2(4)、ACTION3(1),并在枚举中提供一个构造函数,将参数存储到您在比较器中使用的字段。
  3. 创建一个进程列表,在其中按所需顺序添加所有常量,然后在比较器中使用 list.indexOf。这比方法 1 或 2 慢,但这可能不是问题,具体取决于您使用它的位置。

Three solutions come to my mind:

  1. You specify the enum constants in the order you need and use p.ordinal() in the comparator.
  2. You specify ordering index as a parameter for the enum constant, e.g. ACTION1(3), ACTION2(4), ACTION3(1), and provide a constructor in the enum that stores the parameter to a field, which you use in the comparator.
  3. Create a list of Processes where you add all the constants in the order you want, and then use list.indexOf in the comparator. This is slower than approach 1 or 2, but that might not be a problem depending where you are using it.
内心荒芜 2024-10-27 03:26:12

为了扩展 msell 的答案#3(保留列表并使用 indexOf 来计算排序顺序),这在强烈推荐(至少对我来说)中非常简单 Guava 库,使用 Ordering 类:

private static final List<AgentProcess> PREFERRED_ORDER = ImmutableList.of(ACTION1, ACTION19, ACTION27 /* ... */);
private static final Comparator<AgentProcess> PROCESS_COMPARATOR = Ordering.explicit(PREFERRED_ORDER);

非常好,恕我直言。

To expand on msell's answer #3 (keeping a list and using an indexOf to work out the sort order), this is trivially easy in the highly-recommended (at least by me) Guava library, using the Ordering class:

private static final List<AgentProcess> PREFERRED_ORDER = ImmutableList.of(ACTION1, ACTION19, ACTION27 /* ... */);
private static final Comparator<AgentProcess> PROCESS_COMPARATOR = Ordering.explicit(PREFERRED_ORDER);

Very nice, IMHO.

拥抱影子 2024-10-27 03:26:12

http://download.oracle.com/javase/tutorial/ 无耻地窃取java/javaOO/enum.html

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);
/* method declarations and more! */

整洁,我从来没有想过我会看到任何语言中附加到枚举的成对浮点数。 :)

Stolen shamelessly from http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);
/* method declarations and more! */

Neat, I never thought I'd see pairs of floats attached to enums in any language. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文