Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中如何按多级字段对arraylist排序_Java_Arrays_Algorithm - Fatal编程技术网

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的文章后编辑:您在这里描述的问题无法通过正常排序完成,因为根据这些规则,您总是可以构建一个场景,在该场景中,您可以在排序层次结构中获得一个循环。因此,不可能只用这些数据来制作一个可传递的比较器

据我所知,由于可能出现以下循环(粗线-预处理器,细线-大于),您根本无法使比较器传递:

因此,您有一个偏序,通用排序算法在这里不适用

如果您只需要按级别订购