Примеры Java для группировки в стиле SQL по сортировке списка объектов. Это подразумевает использование нескольких компараторов, каждый из которых способен сортировать по разным полям в объекте модели.
1. Класс модели и множественные компараторы
Наш модельный класс — Employee с 4 простыми полями.
package com.howtodoinjava.compare;public class Employee implements Comparable<Employee> {private Integer id = -1;private Integer age = -1;private String firstName = null;private String lastName = null;public Employee(Integer id, String fName, String lName, Integer age) {this.id = id;this.firstName = fName;this.lastName = lName;this.age = age;}//Getters and Setters@Overridepublic String toString() {return "\nEmployee [id=" + id + ", age=" + age + ", firstName=" + firstName + ", lastName=" + lastName + "]";}}
А множественные компараторы предназначены для полей имени, фамилии и возраста.
package com.howtodoinjava.compare;import java.util.Comparator;public class FirstNameSorter implements Comparator<Employee>{public int compare(Employee o1, Employee o2){return o1.getFirstName().compareTo(o2.getFirstName());}}public class LastNameSorter implements Comparator<Employee>{public int compare(Employee o1, Employee o2){return o1.getLastName().compareTo(o2.getLastName());}}public class AgeSorter implements Comparator<Employee>{public int compare(Employee o1, Employee o2){return o1.getAge() - o2.getAge();}}
2. Группировка Java по сортировке – Comparator.thenComparing()
Сортировка списка в Java 8 очень проста благодаря встроенной поддержке цепочки компараторов. Вы создали независимый сортировщик полей, реализовав интерфейс Comparator, и объединили их в методе Collection.sort().
package com.howtodoinjava.compare;import java.util.Arrays;import java.util.Collections;import java.util.List;public class MultipleFieldSorter{public static void main(String[] args){List<Employee> list = Arrays.asList(new Employee(1, "A", "B", 34),new Employee(4, "C", "D", 30),new Employee(3, "B", "A", 31),new Employee(2, "D", "C", 25));Collections.sort(list, new FirstNameSorter().thenComparing(new LastNameSorter()).thenComparing(new AgeSorter()));System.out.println(list);}}
Вывод программы:
[Employee [id=1, age=34, firstName=A, lastName=B],Employee [id=3, age=31, firstName=B, lastName=A],Employee [id=4, age=30, firstName=C, lastName=D],Employee [id=2, age=25, firstName=D, lastName=C]]
3. Группировка Java по сортировке – CompareToBuilder
Значения сравниваются в порядке их добавления к строителю. Если какое-либо сравнение возвращает ненулевой результат, то это значение будет результатом, возвращаемым CompareToBuilder.toComparison(), и все последующие сравнения пропускаются.
3.1 Общая зависимость Apache Lang3
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.7</version></dependency>
3.2. Измените метод compareTo() в модели
package com.howtodoinjava.compare;import org.apache.commons.lang3.builder.CompareToBuilder;public class Employee implements Comparable<Employee> {private Integer id = -1;private Integer age = -1;private String firstName = null;private String lastName = null;public Employee(Integer id, String fName, String lName, Integer age) {this.id = id;this.firstName = fName;this.lastName = lName;this.age = age;}public int compareTo(Employee o) {if(o == null) {return -1;}CompareToBuilder buider = new CompareToBuilder();return buider.append(this.getFirstName(), o.getFirstName()).append(this.getLastName(), o.getLastName()).append(this.getAge(), o.getAge()).toComparison();}//getters and setters}
3.3 Сортировать список
public class MultipleFieldSorter{@SuppressWarnings("unchecked")public static void main(String[] args){List<Employee> list = //list of employees;Collections.sort(list);System.out.println(list);}}
3.4 CompareToBuilder с интерфейсом компаратора
Если вы не хотите изменять интерфейс Comparable, вы все равно можете использовать интерфейс Comparator для сортировки списка с помощью CompareToBuilder.
package com.howtodoinjava.compare;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.List;import org.apache.commons.lang3.builder.CompareToBuilder;public class MultipleFieldSorter{public static void main(String[] args){List<Employee> list = Arrays.asList(new Employee(1, "A", "B", 34),new Employee(4, "C", "D", 30),new Employee(3, "B", "A", 31),new Employee(2, "D", "C", 25));Collections.sort(list, new Comparator<Employee>(){public int compare(Employee empOne, Employee empTwo){return new CompareToBuilder().append(empOne.getFirstName(), empTwo.getFirstName()).append(empOne.getLastName(), empTwo.getLastName()).append(empOne.getAge(), empTwo.getAge()).toComparison();}});System.out.println(list); //Sorted list}}
4. Группировка Java по сортировке – ComparisonChain
Подобно CompareToBuilder из Apache Common lang, библиотека Google Guava предоставляет полезный класс ComparisonChain для сортировки списка объектов.
4.1 Зависимость от гуавы
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>23.0</version></dependency>
4.2. Пример цепочки сравнения
package com.howtodoinjava.compare;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.List;import com.google.common.collect.ComparisonChain;public class MultipleFieldSorter{public static void main(String[] args){List<Employee> list = Arrays.asList(new Employee(1, "A", "B", 34),new Employee(4, "C", "D", 30),new Employee(3, "B", "A", 31),new Employee(2, "D", "C", 25));Collections.sort(list, new Comparator<Employee>(){public int compare(Employee empOne, Employee empTwo){return ComparisonChain.start().compare(empOne.getFirstName(), empTwo.getFirstName()).compare(empOne.getLastName(), empTwo.getLastName()).compare(empOne.getAge(), empTwo.getAge()).result();}});System.out.println(list);}}
5. Группировка по сортировке Java – Связанные компараторы
Это самый простой пример использования нескольких компараторов для сортировки объектов списка по нескольким полям. В этом подходе создается упорядоченный список компараторов и передается методу, который выполняет итерацию по компараторам и использует каждый компаратор для сортировки текущего списка.
5.1 Сортировщик групп
package com.howtodoinjava.compare;import java.util.Arrays;import java.util.Comparator;import java.util.List;public class GroupBySorter implements Comparator<Employee> {private List<Comparator<Employee>> listComparators;public GroupBySorter(Comparator<Employee>... comparators) {this.listComparators = Arrays.asList(comparators);}public int compare(Employee empOne, Employee empTwo) {for(Comparator<Employee> comparator : listComparators) {int result = comparator.compare(empOne, empTwo);if(result != 0) {return result;}}return 0;}}
5.2. Применение группировки по сортировке в списке
Теперь мы можем использовать GroupBySorter выше для сортировки списка сотрудников. Ниже код сортирует список сотрудников в следующем порядке:
- Имя
- Фамилия
- Возраст
package com.howtodoinjava.compare;import java.util.Arrays;import java.util.Collections;import java.util.List;public class MultipleFieldSorter{@SuppressWarnings("unchecked")public static void main(String[] args){List<Employee> list = Arrays.asList(new Employee(1, "A", "B", 34),new Employee(4, "C", "D", 30),new Employee(3, "B", "A", 31),new Employee(2, "D", "C", 25));Collections.sort(list, new GroupBySorter(new FirstNameSorter(), new LastNameSorter(), new AgeSorter()));System.out.println(list);}}
Ссылки:
ComparisonChain Java Doc
Java Doc для CompareToBuilder
Comparator.thenComparing() Java Doc
Сопоставимый документ Java