Java中如何按多级字段对arraylist排序
我的程序创建Java中如何按多级字段对arraylist排序,java,arrays,algorithm,Java,Arrays,Algorithm,我的程序创建活动的实例,将它们放在一个数组列表中,并按两个字段对它们进行排序级别和前置。首先比较前人 例如,如果前置项不是null,则当前活动的前置项活动应该是第一个,它将是第二个。在满足前置条件后,可按级别订购以下物品 Class Activity{ private int level; private Activity predecessor; } List activities=new ArrayList(); //添加一些活动。 活动。添加(活动); 活动。添加(活动)
活动的实例
,将它们放在一个数组列表中,并按两个字段对它们进行排序级别
和前置
。首先比较前人
例如,如果前置项
不是null
,则当前活动的前置项活动应该是第一个,它将是第二个。在满足前置
条件后,可按级别
订购以下物品
Class Activity{
private int level;
private Activity predecessor;
}
List activities=new ArrayList();
//添加一些活动。
活动。添加(活动);
活动。添加(活动);
排序(活动,getActivityComparator());
专用比较器getActivityComparator(){
返回新的比较器(){
公共整数比较(活动act1,活动act2){
如果(act1==null){
如果(act2==null){
返回0;//两个活动都为null
}否则{
return-1;//act1为NULL,因此将act1放在
//已排序的列表
}
}否则{
如果(act2==null){
返回1;
}
}
Activity preAct2=act2.getPreference();
if(preAct2!=null&&preAct2==act1)
返回-1;
//在Joeri Hendrickx的建议中加入了这一点
Activity preAct1=act1.getPreference();
if(preAct1!=null&&preAct1==act2)
返回1;
返回act2.getLevel()-act1.getLevel();
}
};
}
我已经编写了上面的代码并进行了大量测试,但是如果我将不同的顺序放入ArrayList中,它会输出不稳定的顺序。所以这绝对是不正确的实现方法。似乎根本原因不是每两个元素都进行了比较。表示活动act1>活动act2(按级别条件),活动act2>活动act3(按级别条件),并不表示活动act1>活动act3(按级别条件)
在这里,我提出了一个新想法,即使用冒泡排序,而不是使用集合的接口排序。它将比较不再需要comparator transitive的每两个元素。你觉得怎么样
有人能帮我吗?比较器的比较方法定义为: 比较其两个参数的顺序。当第一个参数小于、等于或大于第二个参数时,返回负整数、零或正整数 这意味着如果希望act1在其为null时位于末尾,则必须返回一个正整数->act1大于->act1将位于末尾。 正整数和负整数混合在一起
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();
}
};
}
此外,出于同样的原因,您需要使用
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;
}
}
对接收2和3的整数的比较器进行成像。
您希望它返回负整数,因为第一个参数小于第二个参数。->arg1-arg2=-1
比较器的比较方法定义为: 比较其两个参数的顺序。当第一个参数小于、等于或大于第二个参数时,返回负整数、零或正整数 这意味着如果希望act1在其为null时位于末尾,则必须返回一个正整数->act1大于->act1将位于末尾。 正整数和负整数混合在一起
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();
}
};
}
此外,出于同样的原因,您需要使用
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;
}
}
对接收2和3的整数的比较器进行成像。
您希望它返回负整数,因为第一个参数小于第二个参数。->arg1-arg2=-1
而不是像您那样的arg2-arg1…问题在于您的比较器没有描述正确的对称和传递关系 考虑以下三个对象:
return act1.getLevel()-act2.getLevel();
现在,当comp是比较器时,comp(act1,act2)
将返回-1,但comp(act2,act1)
将返回0。这不是对称的
comp(act1,act2)
将返回-1,comp(act2,act4)
将返回-1,但comp(act1,act4)
将返回1。这不是可传递的
比较器必须描述正确的自反、对称和传递关系才能工作
在看过Axtaxt的文章后编辑:您在这里描述的问题无法通过正常排序完成,因为根据这些规则,您总是可以构建一个场景,在该场景中,您可以在排序层次结构中获得一个循环。因此,不可能只用这些数据来制作一个可传递的比较器 问题在于比较器没有描述正确的对称传递关系 考虑以下三个对象:
return act1.getLevel()-act2.getLevel();
现在,当comp是比较器时,comp(act1,act2)
将返回-1,但comp(act2,act1)
将返回0。这不是对称的
comp(act1,act2)
将返回-1,comp(act2,act4)
将返回-1,但comp(act1,act4)
将返回1。这不是可传递的
比较器必须描述正确的自反、对称和传递关系才能工作
在看过Axtaxt的文章后编辑:您在这里描述的问题无法通过正常排序完成,因为根据这些规则,您总是可以构建一个场景,在该场景中,您可以在排序层次结构中获得一个循环。因此,不可能只用这些数据来制作一个可传递的比较器 据我所知,由于可能出现以下循环(粗线-预处理器,细线-大于),您根本无法使比较器传递: 因此,您有一个偏序,通用排序算法在这里不适用 如果您只需要按级别订购