2012-06-27 39 views
4

如何找到哪个比较器'打破领带'我使用番石榴的Ordering类来执行排序以从给定列表中选择'最佳'。它看起来是这样的:如何在番石榴订购

// Create the Ordering, with a list of Comparators 
Ordering<String> ranker = Ordering.compound(ImmutableList.of(
    STRING_LENGTH, 
    PERCENTAGE_UPPERCASE, 
    NUMBER_OF_VOWELS)); 

// Use the ordering to find the 'best' from a list of Strings 
String best = ranker.max(asList("foo", "fooz", "Bar", "AEro")); 

有了这个Ordering,字符串“AERO”是最好的,因为它是最长的,合资最好的“福兹”,但tiebreaks用大写字符的比例较高。

我正在寻找一种方法来告诉哪个Comparator'打破了领带',在这个愚蠢的人为的例子中将是比较PERCENTAGE_UPPERCASE

我有一个可行的解决方案,但它不是特别优雅,并且意味着重复Comparator s的列表。它是使用Ordering提供一个排序列表(Ordering.sortedCopy),拉动前两个元素(当然是范围检查),遍历相同Comparator s的列表,比较这两个元素,当compareTo方法返回non-零结果。

有没有更好的方法?

回答

3

番石榴贡献者在这里。

你的解决方案似乎喜欢它的,你会得到,但是,而不是做一个排序的副本,并拉动了前两个元素几乎一样好,你应该做的更有效的

List<E> best2 = ranker.greatestOf(list, 2); 

,然后,的确,遍历比较器,尽管你可能会重构,所以你重新使用Ordering.compound的比较器列表,而不是重新创建它。