【问题标题】:Java - Confused about Comparators and need to use one (I think). More info insideJava - 对比较器感到困惑,需要使用一个(我认为)。里面有更多信息
【发布时间】:2012-02-14 00:48:38
【问题描述】:

我创建了一个名为 Foo 的类。 Foo 有三个字段,它们都是整数:x、y 和 z。我想制作一个PriorityQueue<Foo>,它在不同情况下对 Foo 对象的优先级不同。例如,我可能想按 x 值、y 值或 z 进行优先级排序。但是直到运行时我才知道要优先考虑哪个值。我听说您可以使用比较器以某种方式即时强加排序,我认为这在这里会很完美。

不过,我对我将如何做到这一点感到困惑。如果说我想使用比较器优先考虑 x (而不必覆盖我的 Foo 类中的 compareTo 函数),有人可以给我看一个例子吗?

非常感谢。

【问题讨论】:

标签: java comparator


【解决方案1】:

比较器是一个参数化接口,允许您定义如何比较参数化类型的两个实例。假设您有以下课程

class Foo {
   int x;
   int y;
   int z;
}

然后定义一个比较器,根据元素的 x 值排序元素,然后 y 然后 z 我们将执行以下操作

class XyzComparator implements Comparator<Foo> {
    @Override
    public int compare(Foo foo1, Foo foo2) {
          if(foo1.x != foo2.x) {
               return Integer.compare(foo1.x, foo2.x);
          }
          if(foo1.y != foo2.y) {
               return Integer.compare(foo1.y, foo2.y);
          }
          return Integer.compare(foo1.z, foo2.z);
    }
}

同样,您可以定义比较器,首先根据元素的 y 值比较元素,然后根据 x 的 z...等 最后在运行时,您可以使用该比较器实例化一个 PriorityQueue

PriorityQueue<Foo> queue;
if(x_then_y_then_z) {
    queue = new PriorityQueue<Foo>(10, new XyzComparator());
} else if (y_then_x_then_z) {
    queue = new PriorityQueue<Foo>(10, new ZxyComparator());
}

如需了解更多信息,请查看priority queue javadoccomparator javadoc

编辑:请参阅@buritos 关于整数溢出的评论。

【讨论】:

  • 这违反了比较器的合同。在处理数字时在比较中使用减法似乎是正确的,但如果 foo1.y = -2147483648 和 foo2.y = 1 怎么办?显然 foo1.y 小于 foo2.y 但 foo1.y-foo2.y = 2147483647 (因为静默 int 溢出)这显然不是您想要的比较函数的结果。
  • 非常有见地。谢谢你。我将更新代码以反映这一点。
【解决方案2】:
Comparator<Foo> comparator = new Comparator<Foo>() {
  @Override
  public int compare(Foo o1, Foo o2) {
    if (o1.x > o2.x)
      return 1;
    else if(o1.x < o2.x)
      return -1;
    else
      return 0;
  }
};

PriorityQueue<Foo> queue = new PriorityQueue<Foo>(10, comparator);

...

【讨论】:

    猜你喜欢
    • 2017-05-16
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2022-01-07
    • 2014-03-29
    相关资源
    最近更新 更多