如何按String/Enum值对List<Issue>进行单/多字段升降序排序?
解决方案
1. 修复字符串排序的报错问题
你遇到的The method compare(String, String) is undefined for the type String错误,是因为String类没有静态的compare()方法,正确的做法是使用实例方法compareTo(),或者更简洁地用Java 8提供的Comparator工具类来构建排序规则:
比如对title字段降序排序,推荐写法:
return list.stream() .sorted(Comparator.comparing(Issue::getTitle).reversed()) .collect(Collectors.toList());
如果是升序,直接用Comparator.comparing(Issue::getTitle)即可,不需要reversed()。
2. 枚举类型的排序实现
枚举类型的排序分两种场景:
按枚举的自然顺序(定义顺序)排序
Java的枚举默认实现了Comparable接口,排序时会按照枚举在类中定义的顺序来比较。比如IssueElementEnum的自然顺序是PROFILE → ROLE → User,直接用枚举的实例比较即可:
// 按issueElement升序(自然顺序) Comparator.comparing(Issue::getIssueElement) // 按issueElement降序 Comparator.comparing(Issue::getIssueElement).reversed()
按枚举的toString()返回值排序
如果你需要按照枚举重写后的toString()字符串来排序,只需要把比较器的提取函数改成获取toString()结果:
// 按issueElement的toString()升序 Comparator.comparing(issue -> issue.getIssueElement().toString()) // 按issueElement的toString()降序 Comparator.comparing(issue -> issue.getIssueElement().toString()).reversed()
3. 多字段排序的完整实现
针对你需要根据SortDTO[]数组实现多字段排序的需求,我们可以通过构建链式Comparator来实现:先处理第一个排序规则,然后通过thenComparing()依次添加后续的排序规则。
完整代码示例
import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class IssueSorter { // 单字段排序方法(可选保留,作为多字段排序的基础) private List<Issue> sortList(List<Issue> list, String field, String sort) { return list.stream() .sorted(buildSingleFieldComparator(field, sort)) .collect(Collectors.toList()); } // 多字段排序方法 public List<Issue> sortByMultipleFields(List<Issue> list, SortDTO[] sorts) { // 初始化Comparator为null,后续逐步构建 Comparator<Issue> comparator = null; for (SortDTO sortDTO : sorts) { if (sortDTO == null || sortDTO.getField() == null) { continue; // 跳过无效的排序规则 } Comparator<Issue> currentComparator = buildSingleFieldComparator(sortDTO.getField(), sortDTO.getSort()); if (comparator == null) { comparator = currentComparator; } else { comparator = comparator.thenComparing(currentComparator); } } // 如果没有有效的排序规则,返回原集合;否则执行排序 return comparator == null ? list : list.stream() .sorted(comparator) .collect(Collectors.toList()); } // 构建单字段的Comparator private Comparator<Issue> buildSingleFieldComparator(String field, String sort) { boolean isDesc = SortDTO.DESC.equalsIgnoreCase(sort); Comparator<Issue> comparator; switch (field) { case "title": comparator = Comparator.comparing(Issue::getTitle); break; case "issueElement": // 这里可以选择按枚举自然顺序或toString排序,根据你的需求调整 // 示例:按toString()排序 comparator = Comparator.comparing(issue -> issue.getIssueElement().toString()); // 如果要按枚举自然顺序,替换成: // comparator = Comparator.comparing(Issue::getIssueElement); break; case "issueType": comparator = Comparator.comparing(issue -> issue.getIssueType().toString()); // 或按自然顺序:Comparator.comparing(Issue::getIssueType); break; default: // 默认不排序,或抛出异常,根据你的业务需求处理 comparator = (i1, i2) -> 0; break; } // 如果是降序,反转比较器 return isDesc ? comparator.reversed() : comparator; } }
代码说明
buildSingleFieldComparator方法:根据传入的字段名和排序方向,构建对应的Comparator。你可以根据需求选择枚举的排序方式(自然顺序或toString字符串)。sortByMultipleFields方法:遍历SortDTO[]数组,将每个排序规则通过thenComparing()链式拼接,实现多字段排序(先按第一个字段排序,再按第二个字段排序,以此类推)。- 空值处理:跳过无效的排序规则(比如null的SortDTO或空字段名),避免排序出错。
使用示例
针对你给出的示例排序规则[{"field":"title","sort":"asc"},{"field":"issueElement","sort":"desc"}],调用方式如下:
SortDTO[] sorts = { new SortDTO("title", "asc"), new SortDTO("issueElement", "desc") }; List<Issue> sortedIssues = new IssueSorter().sortByMultipleFields(issues, sorts);
内容的提问来源于stack exchange,提问作者Renaud is Not Bill Gates
相关产品推荐
相关产品推荐

