Java多属性自定义排序问题:多元素List的内部排序需求
解决方案:先排序内部列表,再进行整体集合排序
你的问题核心在于:当names或flights是多元素列表时,直接取第一个元素排序会因为内部元素无序导致结果不符合预期。解决思路是先对每个ReservationRow内部的flights和names列表按规则排序,再基于排序后的列表首元素对整个reservationRows集合排序。
步骤1:定义内部列表的排序规则
分别为ReservationFlight和ReservationName定义比较器,确保内部列表元素按业务规则有序:
ReservationFlight:优先按boardPoint升序,再按offPoint升序ReservationName:优先按lastName升序,再按firstName升序
步骤2:实现完整排序逻辑
先通过map操作处理每个ReservationRow的内部列表排序,再对整个集合执行原有的优先级排序。同时加入空值判断避免空指针异常:
private List<ReservationRow> sortRows(List<ReservationRow> reservationRows) { // 定义航班和姓名的内部排序比较器 Comparator<ReservationFlight> flightComparator = Comparator.comparing(ReservationFlight::getBoardPoint) .thenComparing(ReservationFlight::getOffPoint); Comparator<ReservationName> nameComparator = Comparator.comparing(ReservationName::getLastName) .thenComparing(ReservationName::getFirstName); return reservationRows.stream() // 先处理每个ReservationRow的内部列表排序 .map(row -> { // 排序航班列表(非空判断避免NPE) if (row.getFlights() != null && !row.getFlights().isEmpty()) { row.getFlights().sort(flightComparator); } // 排序姓名列表(非空判断避免NPE) if (row.getNames() != null && !row.getNames().isEmpty()) { row.getNames().sort(nameComparator); } return row; }) // 按业务优先级对整个集合排序 .sorted(Comparator.comparing(row -> row.getFlights() != null && !row.getFlights().isEmpty() ? row.getFlights().get(0).getBoardPoint() : "" // 空列表时的默认值,可根据业务调整 ) .thenComparing(row -> row.getFlights() != null && !row.getFlights().isEmpty() ? row.getFlights().get(0).getOffPoint() : "" ) .thenComparing(row -> row.getNames() != null && !row.getNames().isEmpty() ? row.getNames().get(0).getLastName() : "" ) .thenComparing(row -> row.getNames() != null && !row.getNames().isEmpty() ? row.getNames().get(0).getFirstName() : "" )) .toList(); } // 原实体类定义 class ReservationRow { private List<ReservationName> names; private List<ReservationFlight> flights; // 请确保已实现getters和setters } class ReservationName { private String lastName; private String firstName; // 请确保已实现getters和setters } class ReservationFlight { private String boardPoint; private String offPoint; // 请确保已实现getters和setters }
关键说明
- 内部列表排序:通过
map操作遍历每个ReservationRow,对其flights和names列表执行排序,确保后续取第一个元素时是符合规则的“代表元素”。 - 空值处理:加入非空判断避免
NullPointerException,空列表时的默认值(示例中用空字符串)可根据业务需求调整(比如用null或特定占位符)。 - 代码复用:将内部比较器单独提取,提高代码可读性和复用性。
内容的提问来源于stack exchange,提问作者ashish gupta
相关产品推荐
相关产品推荐

