Class Activity{
private int level;
private Activity predecessor;
}
我的程序会创建Activity
的实例,将它们放在Arraylist中,并按两个字段level
和predecessor
对它们进行排序。前人首先进行比较。
例如,如果predecessor
不是null
,则当前活动的前任Activity
应该是第一个,它将是第二个。满足predecessor
条件后,level
可以订购以下内容。
List<Activity> activities = new ArrayList<Activity>();
//Add some activities.
activities.add(Activity);
activities.add(Activity);
Collections.sort(activities,getActivityComparator());
private Comparator<Activity> getActivityComparator() {
return new Comparator<Activity>() {
public int compare(Activity act1, Activity act2) {
if (act1 == null) {
if (act2 == null) {
return 0; // Both activities are null
} else {
return -1; // act1 is NULL, so put act1 in the end of
// the sorted list
}
} else {
if (act2 == null) {
return 1;
}
}
Activity preAct2 = act2.getPredecessor();
if(preAct2!=null&&preAct2==act1)
return -1;
//Adding this by Joeri Hendrickx's suggestion
Activity preAct1 = act1.getPredecessor();
if(preAct1!=null&&preAct1==act2)
return 1;
return act2.getLevel()-act1.getLevel();
}
};
}
我已经编写了上面的代码并进行了大量测试,但是如果我把不同的顺序放到Arrarylist中,它会输出不定的顺序。所以这肯定是不正确的方法来实现这一点。似乎根本原因并不是每两个元素都进行了比较。说活动act1&gt;活动act2(按级别条件),活动act2&gt;活动act3(按级别条件),它不代表活动act1&gt;活动act3(按前身条件)。
在这里,我提出了一个新的想法,即使用冒泡排序而不是使用接口排序集合。它将比较不再需要比较器传递的每两个元素。你觉得怎么样?
任何人都可以帮助我吗?
答案 0 :(得分:3)
问题是你的比较器没有描述正确的对称和传递关系。
考虑以下三个对象:
act1{predecessor:null, level:1}
act2{predecessor:act1, level:1}
act3{predecessor:null, level:0}
act4{predecessor:act2, level:2}
现在,如果comp是比较器,comp(act1, act2)
将返回-1,但comp(act2, act1)
将返回0.这不是对称。
comp(act1, act2)
将返回-1,comp(act2, act4)
将返回-1,但comp(act1, act4)
将返回1.这不是传递。
比较器必须描述正确的自反,对称和传递关系才能使其正常工作。
在看到Axtaxt的帖子后编辑:这里描述的问题无法通过正常排序完成,因为总是可以构建一个场景,通过这些规则,您可以在排序层次结构中获得循环。因此,仅使用此数据来制作传递比较器是不可能的。
答案 1 :(得分:1)
据我了解,由于可能存在以下循环(粗线 - 前驱,细线 - 大于),因此无法使比较器完全传递:
因此,您有一个部分订单,通用排序算法在这里不适用。
如果您只需要在同一活动的后续版本中按级别进行排序,则可以使用以下简单算法来实现:
从Activity
到其直接后继者
使用以下属性构建树:
null
活动
可以使用以下算法创建它:
null
活动
答案 2 :(得分:0)
比较器的比较方法定义为: “比较它的两个参数的顺序。当第一个参数小于,等于或大于第二个参数时,返回一个负整数,零或一个正整数。”
这意味着如果你想让act1在其null时结束,你必须返回一个正整数 - &gt; act1更大 - &gt; act1将结束。 你的正面和负面整数是混合的。
if (act1 == null) {
if (act2 == null) {
return 0; // Both activities are null
} else {
return 1; // act1 is NULL, so put act1 in the end of
// the sorted list
}
} else {
if (act2 == null) {
return -1;
}
}
另外,出于同样的原因,您需要使用
return act1.getLevel()-act2.getLevel();
为接收2和3的整数成像比较器。 您希望它返回负int,因为第一个参数小于第二个参数。 - &GT; arg1-arg2 = -1 而不是像你那样做arg2-arg1 ......