排序是编程中最基础且常见的需求之一。在 Java 中,Comparator 接口是实现定制化排序的强大工具。本文将通过代码示例深入讲解 Comparator 的用法,并结合一个实际的 Spring Boot 项目展示如何在前后端实现排序功能。
Comparator 接口详细介绍
Comparator 是 Java 中用于定义对象排序规则的接口。它位于 java.util 包中,常用于对集合或数组中的对象进行排序。与 Comparable 接口相比,Comparator 更灵活,它允许我们为不同的排序需求定义多个比较器。
- 核心方法
返回负数:o1 小于 o2。
返回零:o1 等于 o2。
返回正数:o1 大于 o2。
- int compare(T o1, T o2)定义两个对象的比较逻辑。
- boolean equals(Object obj)(默认实现):用于比较当前 Comparator 与另一个对象是否相等。
- 常见用法
.匿名内部类直接实现接口并定义排序逻辑。
a.Lambda 表达式在 Java 8 之后,更简洁地实现比较逻辑。
b.方法引用使用已有的方法简化代码。
c.Comparator 的引入极大地提高了排序的灵活性,适用于需要多条件或动态排序的场景。
项目配置
pom.xml 配置
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Spring Boot Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring Boot DevTools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring Boot Configuration Processor -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
application.yaml 配置
custom:
sorting:
criteria:
- name
- age
- city
读取配置类
package com.icoderoad.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Data
@Configuration
@ConfigurationProperties(prefix = "custom.sorting")
public class SortingConfig {
private List<String> criteria;
}
核心代码
实体类
package com.icoderoad.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private int age;
private String city;
}
Comparator 实现
package com.icoderoad.util;
import com.icoderoad.entity.Person;
import java.util.Comparator;
public class PersonComparator {
public static Comparator<Person> byName() {
return Comparator.comparing(Person::getName);
}
public static Comparator<Person> byAge() {
return Comparator.comparingInt(Person::getAge);
}
public static Comparator<Person> byCity() {
return Comparator.comparing(Person::getCity);
}
}
服务层
package com.icoderoad.service;
import com.icoderoad.config.SortingConfig;
import com.icoderoad.entity.Person;
import com.icoderoad.util.PersonComparator;
import org.springframework.stereotype.Service;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class PersonService {
private final SortingConfig sortingConfig;
public PersonService(SortingConfig sortingConfig) {
this.sortingConfig = sortingConfig;
}
public List<Person> sortPersons(List<Person> persons, String criteria) {
Comparator<Person> comparator;
switch (criteria) {
case "age":
comparator = PersonComparator.byAge();
break;
case "city":
comparator = PersonComparator.byCity();
break;
case "name":
default:
comparator = PersonComparator.byName();
break;
}
return persons.stream().sorted(comparator).collect(Collectors.toList());
}
}
控制器层
package com.icoderoad.controller;
import com.icoderoad.entity.Person;
import com.icoderoad.service.PersonService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Arrays;
import java.util.List;
@Controller
public class PersonController {
private final PersonService personService;
public PersonController(PersonService personService) {
this.personService = personService;
}
@GetMapping("/persons")
public String getPersons(@RequestParam(defaultValue = "name") String criteria, Model model) {
List<Person> persons = Arrays.asList(
new Person("Alice", 30, "New York"),
new Person("Bob", 25, "San Francisco"),
new Person("Charlie", 35, "Chicago")
);
model.addAttribute("persons", personService.sortPersons(persons, criteria));
model.addAttribute("criteria", criteria);
return "persons";
}
}
前端实现
persons.html 模板
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Person List</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<h1>人员列表</h1>
<form method="get" action="/persons">
<select name="criteria" class="form-select" onchange="this.form.submit()">
<option value="name" th:selected="${criteria == 'name'}">按姓名排序</option>
<option value="age" th:selected="${criteria == 'age'}">按年龄排序</option>
<option value="city" th:selected="${criteria == 'city'}">按城市排序</option>
</select>
</form>
<table class="table table-striped mt-3">
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
<th>城市</th>
</tr>
</thead>
<tbody>
<tr th:each="person : ${persons}">
<td th:text="${person.name}"></td>
<td th:text="${person.age}"></td>
<td th:text="${person.city}"></td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
通过以上代码,我们展示了如何使用 Java Comparator 实现定制化排序,并在 Spring Boot 项目中将排序功能集成到前后端,最终呈现了一个可交互的人员列表。希望本文能够帮助你深入理解 Comparator 的用法!