У меня есть список объектов. Каждый объект содержит String
и Date
(среди прочих).
Я хочу сначала отсортировать по String
, а затем по Date
.
Как это можно сделать самым чистым способом?
Спасибо!
Krt_Maltap >
У меня есть список объектов. Каждый объект содержит String
и Date
(среди прочих).
Я хочу сначала отсортировать по String
, а затем по Date
.
Как это можно сделать самым чистым способом?
Спасибо!
Krt_Maltap >
Учитывая класс объекта, который выглядит следующим образом:
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());
С Java 8 это очень просто. Учитывая,
class MyClass {
String getString() { ... }
Date getDate() { ... }
}
Вы можете легко отсортировать список следующим образом:
List<MyClass> list = ...
list.sort(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate));
Ответ компараторов правильный, но неполный.
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 имеет хороший метод утилиты для объединения разных компараторов, чтобы избавить вас от написания этого шаблона. Дополнительную информацию см. В chainComparators.
Внедрите Comparator
, используя compare(a,b)
, как показано ниже:
Обычная 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;
}
С Guava (используя ComparisonChain
):
public int compare(YourObject o1, YourObject o2) {
return ComparisonChain.start()
.compare(o1.getProperty1(), o2.getProperty1())
.compare(o1.getProperty2(), o2.getProperty2())
.result();
}
С Commons/Lang (используя CompareToBuilder
):
public int compare(YourObject o1, YourObject o2) {
return new CompareToBuilder()
.append(o1.getProperty1(), o2.getProperty1())
.append(o1.getProperty2(), o2.getProperty2())
.toComparison();
}
(Все три версии эквивалентны, но простая Java-версия является самой многословной и, следовательно, самой подверженной ошибкам. Все три решения предполагают, что o1.getProperty1()
и o1.getProperty2()
реализуют Comparable
).
(взято из этого предыдущего моего ответа)
Попробуйте этот метод:
Collections.sort(list, comparator)
Разумеется, для вашего объекта должна быть реализована пользовательская реализация Comparator, как указано Manoj.
Используя 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);