在Java中使用2个条件对列表进行排序

在Java中使用2个条件对列表进行排序,java,sorting,Java,Sorting,我有一个物品清单。每个对象包含一个字符串和一个日期(除其他外) 我想先按字符串排序,然后按日期排序 如何以尽可能干净的方式做到这一点 谢谢 Krt_Malta试试这个方法: 当然,正如Manoj所说,您的对象应该有一个自定义比较器实现。比较器的答案是正确的,但不完整 StringAndDateComparator implements Comparator<MyObject> { public int compare(MyObject first, MyObject sec

我有一个物品清单。每个对象包含一个
字符串
和一个
日期
(除其他外)

我想先按
字符串
排序,然后按
日期
排序

如何以尽可能干净的方式做到这一点

谢谢

Krt_Malta

试试这个方法:


当然,正如Manoj所说,您的对象应该有一个自定义比较器实现。

比较器的答案是正确的,但不完整

StringAndDateComparator implements Comparator<MyObject> {

   public int compare(MyObject first, MyObject second) {
        int result = first.getString().compareTo(second.getString());
        if (result != 0) {
            return result;
        }
        else {
            return first.getDate().compareTo(second.getDate());
        }
}
StringAndDateComparator实现Comparator{
公共整数比较(MyObject第一,MyObject第二){
int result=first.getString().compareTo(second.getString());
如果(结果!=0){
返回结果;
}
否则{
返回first.getDate().compareTo(second.getDate());
}
}
GlazedList有一个很好的实用方法,可以将不同的比较器链接在一起,从而避免编写此样板文件。有关详细信息,请参阅该方法。

使用如下方法实现自定义:

纯Java:

 public int compare(YourObject o1, YourObject o2) {
    int result = o1.getProperty1().compareTo(o2.getProperty1()));
    if(result==0) result = o1.getProperty2().compareTo(o2.getProperty2());
    return result;
 }
与(使用):

与(使用):

(这三个版本都是等效的,但纯Java版本最冗长,因此最容易出错。这三个解决方案都假定
o1.getProperty1()
o1.getProperty2()
实现
可比性

(摘自)



现在,给定一个如下所示的对象类,执行以下操作:

public class MyObject {
    public String getString() { ... }
    public Date getDate() { ... }
    ...
}
编写一个自定义比较器类,如下所示:

public class ObjectComparator implements Comparator{

    public int compare(Object obj1, Object obj2) {
        MyObject myObj1 = (MyObject)obj1;
        MyObject myObj2 = (MyObject)obj2;
        stringResult = myObj1.getString().compareTo(myObj2.getString());
        if (stringResult == 0) {
            // Strings are equal, sort by date
            return myObj1.getDate().compareTo(myObj2.getDate());
        }
        else {
            return stringResult;
        }
    }
}
然后按如下方式排序:

Collections.sort(objectList, new ObjectComparator());
List<MyClass> list = ...
list.sort(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate));
List<Employee> empss  = getEmployees();
Comparator<Employee> combinedComparator = Comparator.comparing(Employee::getFName)
                                                    .thenComparing(Employee::getLName);
Employee[] emppArr = employees.toArray(new Employee[empss.size()]);

//Parallel sorting
Arrays.parallelSort(emppArr, combinedComparator);

使用Java8,这非常简单

class MyClass {
    String getString() { ... }
    Date getDate() { ... }
}
您可以按如下方式轻松对列表进行排序:

Collections.sort(objectList, new ObjectComparator());
List<MyClass> list = ...
list.sort(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate));
List<Employee> empss  = getEmployees();
Comparator<Employee> combinedComparator = Comparator.comparing(Employee::getFName)
                                                    .thenComparing(Employee::getLName);
Employee[] emppArr = employees.toArray(new Employee[empss.size()]);

//Parallel sorting
Arrays.parallelSort(emppArr, combinedComparator);
List=。。。
排序(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate));

使用java 8和并行排序技术,我们还可以实现以下目标:

Collections.sort(objectList, new ObjectComparator());
List<MyClass> list = ...
list.sort(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate));
List<Employee> empss  = getEmployees();
Comparator<Employee> combinedComparator = Comparator.comparing(Employee::getFName)
                                                    .thenComparing(Employee::getLName);
Employee[] emppArr = employees.toArray(new Employee[empss.size()]);

//Parallel sorting
Arrays.parallelSort(emppArr, combinedComparator);
List emps=getEmployees();
Comparator combinedComparator=Comparator.comparing(Employee::getFName)
.然后比较(雇员::getLName);
Employee[]emppar=employees.toArray(新员工[empss.size()]);
//并行排序
并行排序(emppArr,组合比较器);
包core.java.collection;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.Comparator;
导入java.util.List;
公共类GroupByComparator{
公共静态void main(字符串[]args){
List studList=new ArrayList();
学生测试s1=新学生测试(12,“Devendra”,410);
学生测试s2=新学生测试(11,“Devendra”,430);
学生测试s3=新学生测试(13,“Devendra”,402);
学生测试s4=新学生测试(10,“Devendra”,432);
//假设id可能相同
学生测试s5=新学生测试(14,“Singraul”,432);
学生测试s6=新学生测试(14,“阿布舍克”,432);
学生测试s7=新学生测试(14,“Roshan”,432);
学生测试s8=新学生测试(14,“比卡斯”,432);
学生测试s9=新学生测试(15,“Devlal”,450);
学生测试s10=新学生测试(15,“Devlal”,359);
学生测试s11=新学生测试(15,“Devlal”,430);
学生测试s12=新学生测试(15,“Devlal”,420);
studList.add(s1);studList.add(s2);studList.add(s3);studList.add(s4);studList.add(s5);
studList.add(s6);studList.add(s7);studList.add(s8);studList.add(s9);studList.add(s10);
studList.add(s11);studList.add(s12);
排序(studList,newstudentcomparator());
//按排序分组
系统输出打印项次(studList);
}
}
//升序分组比较器
类StudentComparator实现Comparator{
@凌驾
公共整数比较(StudentTest newObj、StudentTest oldObj){
int结果=0;
//先按名字排序
结果=newObj.getStudName().compareTo(oldObj.getStudName());
//按学生id排序第二
如果(结果==0){
result=newObj.getStudId()-oldObj.getStudId();//之前为负
}
//按第三个标记排序
如果(结果==0){
result=Float.compare(newObj.getMarks(),oldObj.getMarks());;//之前为负数
}
返回结果;
}
}
班级学生测验{
私立国际学生会;
私有字符串名称;
私人浮标;
公共StudentTest(int studId、字符串studName、浮点数){
超级();
this.studId=studId;
this.studName=studName;
这个。标记=标记;
}
public int getStudId(){
返回studId;
}
公共无效设置studId(int studId){
this.studId=studId;
}
公共字符串getStudName(){
返回studName;
}
public void setStudName(字符串studName){
this.studName=studName;
}
公众浮点数(){
返回标记;
}
公共无效设置标记(浮动标记){
这个。标记=标记;
}
@凌驾
公共字符串toString(){
返回“StudentTest[studId=“+studId+”,studName=“+studName+”,marks=“+marks+””;
}

}

可以使用2个lambda表达式对简单数组进行排序,如下所示:

Arrays.sort(arr, (i, j) -> (i[0] == j[0] ? j[1] - i[1] : i[0] - j[0]));
表示二维数组中的两个子数组i&jarr将根据数组的第0个索引按升序排序。如果第0个索引相等,则根据第1个索引进行排序。

请尝试这种方法。<

studentlist.stream().sorted(Comparator.comparing(Student::getAge).thenComparing(Student::getName)).forEach(System.out::println);

@Krt_Malta是最清楚的吗?我不这么认为。首先,它使用了comparator的pre-1.5非通用版本,它更详细,更容易出错。例如,I82Much的答案要好得多。我实际上同意我自己,我应该使用comparator的通用版本,番石榴比较链听起来很值得一看如果你愿意将这种依赖性引入到你的项目中,你就可以考虑(可能它还有很多其他的好东西)@出于好奇,如果你同意使用Comparator更好,为什么不编辑你的答案呢?目前I82Much的答案在投票中排名第三,所以一些非常匆忙的人可能不会阅读它或这些评论,而只是在没有泛型的情况下实现你的答案。