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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5594994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:49:51  来源:igfitidea点击:

Sorting a list in Java using 2 criteria

javasorting

提问by Krt_Malta

I have a list of objects. Each object contains a Stringand a Date(amongst others).

我有一个对象列表。每个对象都包含一个String和一个Date(等等)。

I want to first sort by the Stringand then by the Date.

我想先按 排序String,然后按Date.

How could this be done in the cleanest way possible?

这怎么可能以最干净的方式完成?

Thanks!

谢谢!

Krt_Malta

Krt_马耳他

回答by Lukas Eder

With Java 8, this is really easy. Given

使用 Java 8,这真的很容易。给定的

class MyClass {
    String getString() { ... }
    Date getDate() { ... }
}

You can easily sort a list as follows:

您可以轻松地按如下方式对列表进行排序:

List<MyClass> list = ...
list.sort(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate));

回答by unnamedwill

Given an object class that looks like this:

给定一个如下所示的对象类:

public class MyObject {
    public String getString() { ... }
    public Date getDate() { ... }
    ...
}

Write a custom comparator class like so:

编写一个自定义比较器类,如下所示:

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;
        }
    }
}

Then sort as follows:

然后排序如下:

Collections.sort(objectList, new ObjectComparator());

回答by Sean Patrick Floyd

Implement a custom Comparator, using a compare(a,b)method like the following:

Comparator使用compare(a,b)如下方法实现自定义:

Plain 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;
 }

With Guava(using ComparisonChain):

使用番石榴(使用ComparisonChain):

public int compare(YourObject o1, YourObject o2) {
    return ComparisonChain.start()
      .compare(o1.getProperty1(), o2.getProperty1())
      .compare(o1.getProperty2(), o2.getProperty2())
      .result();
 }

With Commons / Lang(using CompareToBuilder):

使用Commons / Lang(使用CompareToBuilder):

public int compare(YourObject o1, YourObject o2) {
    return new CompareToBuilder()
      .append(o1.getProperty1(), o2.getProperty1())
      .append(o1.getProperty2(), o2.getProperty2())
      .toComparison();
 }

(All three versions are equivalent, but the plain Java version is the most verbose and hence most error-prone one. All three solutions assume that both o1.getProperty1()and o1.getProperty2()implement Comparable).

(所有三个版本都是等价的,但纯 Java 版本是最冗长的,因此最容易出错。所有三个解决方案都假设o1.getProperty1()和 都o1.getProperty2()实现了Comparable)。

(Taken from this previous answer of mine)

(取自我之前的回答



now do Collections.sort(yourList, yourComparator)

现在做 Collections.sort(yourList, yourComparator)

回答by I82Much

The Comparators answer is correct but incomplete.

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

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());
        }
}

GlazedLists has a nice utility method to chain together different comparators to save you from writing this boilerplate. See the chainComparatorsmethod for more information.

GlazedLists 有一个很好的实用方法,可以将不同的比较器链接在一起,从而避免编写这个样板文件。有关更多信息,请参阅chainComparators方法。

回答by Guillaume

Try this method:

试试这个方法:

Collections.sort(list, comparator)

Collections.sort(list, comparator)

You should of course have a custom Comparator implementation for your object, as stated by Manoj.

正如 Manoj 所述,您当然应该为您的对象自定义 Comparator 实现。

回答by KayV

Using java 8 and parallel sorting technique, we can also achieve this as follows:

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

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);

回答by Devendra Singraul

 package core.java.collection;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class GroupByComparator {

public static void main(String[] args) {

List <StudentTest>  studList = new ArrayList<StudentTest>(); 

    StudentTest s1 = new StudentTest(12 ,"Devendra" ,410);
    StudentTest s2 = new StudentTest(11 ,"Devendra" ,430);
    StudentTest s3 = new StudentTest(13 ,"Devendra" ,402);
    StudentTest s4 = new StudentTest(10 ,"Devendra" ,432);
    //Assuming that id may be same
    StudentTest s5 = new StudentTest(14 ,"Singraul" ,432);
    StudentTest s6 = new StudentTest(14 ,"Abhishek" ,432);
    StudentTest s7 = new StudentTest(14 ,"Roshan" ,432);
    StudentTest s8 = new StudentTest(14 ,"Bikas" ,432);

    StudentTest s9 = new StudentTest(15 ,"Devlal" ,450);
    StudentTest s10 = new StudentTest(15 ,"Devlal" ,359);
    StudentTest s11= new StudentTest(15 ,"Devlal" ,430);
    StudentTest s12 = new StudentTest(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);

    Collections.sort(studList, new StudentComparator());
    // group by sorting
    System.out.println(studList);

}

}

 // Group by Comparator for ascending order
 class StudentComparator implements Comparator<StudentTest>{

@Override
public int compare(StudentTest newObj, StudentTest oldObj) {
    int result =0;
    // sort by name  first 
    result=  newObj.getStudName().compareTo(oldObj.getStudName());
    // sort by student id  second
    if(result == 0) {
        result=  newObj.getStudId()-oldObj.getStudId() ; // negative means before
    }
     // sort by marks third
    if(result == 0) {
        result=   Float.compare(newObj.getMarks(), oldObj.getMarks()); ; // negative means before
    }

    return result;
}

  }

class StudentTest{

private int studId ;
private String studName ;
private float marks ;

public StudentTest(int studId, String studName, float marks) {
    super();
    this.studId = studId;
    this.studName = studName;
    this.marks = marks;
}

public int getStudId() {
    return studId;
}

public void setStudId(int studId) {
    this.studId = studId;
}

public String getStudName() {
    return studName;
}

public void setStudName(String studName) {
    this.studName = studName;
}

public float getMarks() {
    return marks;
}

public void setMarks(float marks) {
    this.marks = marks;
}

@Override
public String toString() {
    return "StudentTest [studId=" + studId + ", studName=" + studName + ", marks=" + marks + "]";
}

}

}