我有一个列表,需要根据两个条件进行排序。Boolean
假设第一个条件是a isBig
。第二个是a Long
,代表时间戳。
我需要以这种方式对列表中的元素进行排序:在之前isBig = true
,然后在isBig = false
。在这些组中,单个元素应根据其时间戳降序排列。
基本上,我希望结果是这样的:
isBig - 2015/10/29
isBig - 2015/10/28
isBig - 2015/10/27
!isBig - 2015/10/30
!isBig - 2015/10/27
!isBig - 2015/10/26
假设对象是这样的:
public class Item {
Boolean isBig;
Long timestamp;
// ...
}
列表就是List<Item> list
。
我发现一种方法是进行三个循环:第一个组成两个组:isBig
和!isBig
。第二个和第三个用于对其中的元素进行排序。最后,我将两个列表合并。
是否存在基于两个条件对列表进行排序的更有效算法?
您可以使用检查两个条件的自定义比较方法直接对列表进行排序。
使用该Collections.sort
方法,并将自定义比较器(该方法被compare
覆盖)传递给:
int compare(Item o1, Item o2) {
if (o1.isBig && !o2.isBig)
return -1;
if (!o1.isBig && o2.isBig)
return 1;
if (o1.timestamp < o2.timestamp)
return -1;
if (o1.timestamp > o2.timestamp)
return 1;
return 0;
}
如果您沉迷于性能,则可以使用更复杂的方法将性能提高几个百分点,但是对于数百个元素的列表而言,增益可以忽略不计。
一种优化的比较方法:
int compare(Item o1, Item o2) {
int bigness = (o2.isBig ? 2 : 0) - (o1.isBig ? 2 : 0);
long diff = o1.timestamp - o2.timestamp;
return bigness + (int) Long.signum(diff);
}
它没有条件分支,这意味着它可能比上面的幼稚版本要快。
那可能就是可以为性能而做的所有事情。如果我们对您的数据了解更多(例如,大对象总是多于小对象,或者所有时间戳都是唯一的,或者所有时间戳都来自某个狭窄范围等),我们可能会提出一些更好的解决方案。但是,当我们假设您的数据是任意的并且没有特定的模式时,最好的解决方案是使用如上所示的标准排序实用程序。
将列表分为两个子列表并分别对其进行排序肯定会比较慢。实际上,排序算法很可能会将数据分为两组,然后递归地分为四组,依此类推。但是,该划分不会遵循该isBig
标准。如果您想了解更多信息,请阅读快速排序或合并排序的工作方式。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句