我可以使用Collections.sort与quasiorder吗?

时间:2015-10-13 21:30:51

标签: java sorting comparator preorder

总quasiorder(也称为总预订单)是一种较弱的排序关系,允许两个不同的元素被认为是#34;相同的大小"。例如,所有字符串的集合按长度准排序,因为两个不同的字符串可以具有相同的长度。

现在假设我们有一个字符串列表,我们想按长度排序(最短的第一个)。如果两个字符串具有相同的长度,我们不关心哪个首先出现。 乍一看,写

似乎是合理的
Collections.sort(list, (s, t) -> s.length() - t.length());

不幸的是,这是非法的。比较器接口的Javadoc没有明确的条款要求比较必须实现总排序。这是违反的,因为" a" .length() - " b" .length()等于0,但是" a" .equals(" b&# 34;)是假的。

那么,我们该如何干净地做到这一点呢?干净地说,我的意思是不引入虚假的比较,例如:通过哈希码或自然排序。

2 个答案:

答案 0 :(得分:1)

使用长度的解决方案确实提供了total ordering

"a".length() - "b".length() == 0指的是什么,但"a".equals("b") == false不是总排序。它与与equals 一致。在这一点上,documentation for the Comparable interface说:

  

当且仅当c.compare(e1,e2)== 0具有与e1.equals(e2)相同的布尔值时,比较器c对一组元素S施加的排序被认为与equals一致。对于S中的每个e1和e2。

这并不意味着你 提供一个与equals一致的比较器。

答案 1 :(得分:1)

您误解了文档。当他们说

  

比较函数,它对某些对象集合施加总排序。

定义,而不是要求。对于给定的Comparatorc,如果c.compare(o1, o2) == 0,则用于c o1o2定义的订单Comparator是平等的。

文档继续讨论Comparator对于&#34;与equals&#34;一致意味着什么,这基本上意味着equals()中固有的平等感,如上所述,与允许对象中固有的对象相同。 Comparator方法。该讨论是基于某些Comparator不具备该特征的可能性,而您提出的那个特征并非如此。使用这样的SortedSet订购SortedMapComparator可能会产生违反这些接口合同的行为,但使用此类Collections.sort()并没有错与$picks = User::find($user->id)->picks()->where('week', $currentWeek); foreach ($picks as $pick){ $pickWhereGameStarted = $pick->schedule()->where('gameTime', '<', Carbon::now())->get(); }