【问题标题】:Best way of creating a Comparator that reverses order创建倒序比较器的最佳方法
【发布时间】:2014-06-25 04:25:05
【问题描述】:

这似乎是一个愚蠢的问题,但我想询问以相反顺序对可排序结构(任何类型,可以是 List)的类 MyClass 进行排序的最佳方法。实现Comparable

首先,由于MyClass 没有实现Comparable 并且我想对其进行排序,因此我创建了一个Comparator,如下所示:

public class MyClassComparator implements Comparator<MyClass> {
    @Override
    public int compare(MyClass o1, MyClass o2) {
        return (o1.getMyField()).compareTo(o2.getMyField());
    }
}

当然,这会根据 MyClass.MyField 的自然顺序对 MyClass 对象进行排序。但我想要相反的顺序。

我当然可以在compare(MyClass o1, MyClass o2) 方法中硬编码相反的顺序。类似的东西

if (o1.getMyField()).compareTo(o2.getMyField()) > 0 return -1;
if (o1.getMyField()).compareTo(o2.getMyField()) < 0 return 1;
return 0;

另一种选择是保留我最初建议的 MyClassComparator 的代码,并使用 java.util.Collections 中的 public static &lt;T&gt; Comparator&lt;T&gt; reverseOrder(Comparator&lt;T&gt; cmp) 传递 MyClassComparator 的实例并获得反向比较器。

我认为错误的第三种选择可能是使用自然顺序比较器对我的LinkedList&lt;MyClass&gt; 进行排序,并从最后一个到第一个获取元素。 LinkedList 是一个双向链表,所以它应该可以完美地处理这个问题。问题是我总是必须得到一个特定的 Iterator 而不是仅仅使用 for each 循环(次要),当然,我最初想对任何可排序的结构进行排序,我不能保证它将是一个双向链表或任何可以很好地以相反顺序遍历它的东西。

考虑到我很确定(永远不能 100% 确定)我不会使用 MyClass 对象的自然顺序,只是相反的顺序,那么获得我的反向比较器?

谢谢。

【问题讨论】:

  • 您可以:比较 o2o1 而不是...(o2.getMyField()).compareTo(o1.getMyField());使用Collections.reverse 或如您所说,使用Collections.reverseOrder,我认为这是最有效的,因为您不会重复处理集合
  • @Blueriver 不确定您所说的“最佳”方式的真正含义,您自己概述的解决方案都是合理的:) 就个人而言,我已经成功使用了 reverseOrder() 选项,我发现它是最干净的:你构建你的比较器来按升序对你的项目进行排序,然后用一行优雅的代码得到一个完全相反的项目。
  • 感谢@NotSoOldNick。猜测“最好”是指最干净、最容易维护,当然也尽可能高效。 @MadProgrammer 使用 reverse() 是不可能的,因为 javadoc 说“这个方法在线性时间内运行”。 ,这意味着它遍历已排序的 Collection 以对其进行反向排序。如果我可以从一开始就以相反的顺序对我的集合进行排序,那根本就没有效率。比较 o2 和 o1 而不是 o1 和 o2 听起来不错。它会完成这项工作吗?用o2.getMyField().compareTo(o1.getMyField()) 创建一个Comparator,而不是我建议的那个。

标签: java sorting reverse comparator


【解决方案1】:

在这里使用比较器是正确的方法,以避免反转数组的开销。如果您要比较的类实现了 Comparable,您可以颠倒比较的顺序。 obj2.compareTo(obj1)。一种可视化的方法是将两个对象视为整数,并将 compareTo 视为减去它们。

【讨论】:

  • MyClass 上没有Comparable,但MyClass.myField 确实实现了Comparable。你认为最好的方法是写一个Comparator 来实现o2.getMyField().compareTo(o1.getMyField()),而不是我最初创建的o1.getMyField().compareTo(o2.getMyField())
  • 反转顺序似乎是一种更简单、更快捷的解决方案,因为您不需要检查和更改值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-16
  • 2018-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多