Java 8特性实现LocalDate分区排序的最优方案咨询
Java 8特性实现日期排序的优化方案提示
问题核心
你的原实现未通过的主要原因有两点:
- 用硬编码月份数值判断是否含'r',不符合需求中“按月份名称是否包含'r'”的字面规则(虽然数值范围碰巧覆盖了部分含'r'的月份,但逻辑上偏离了需求定义);
- 没有利用Java 8的Stream、Lambda、Comparator组合等特性,不符合招聘方的要求。
优化实现提示
1. 正确判断月份是否含'r'
不要依赖月份数字,直接取月份的英文全称(指定英文Locale),转小写后检查是否包含'r',这是完全贴合需求的判断逻辑:
private boolean hasRInMonth(LocalDate date) { return date.getMonth() .getDisplayName(TextStyle.FULL, Locale.ENGLISH) .toLowerCase() .contains("r"); }
2. 用Java 8 Stream + Comparator组合实现排序
无需手动拆分列表再合并,通过Stream的sorted方法结合自定义Comparator,一步完成多规则排序:
- 第一优先级:含'r'的月份日期排前面,不含的排后面;
- 第二优先级:含'r'的日期按升序排列,不含的按降序排列。
示例实现:
import java.time.LocalDate; import java.time.format.TextStyle; import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; public class DateSorter implements IDateSorter { private boolean hasRInMonth(LocalDate date) { return date.getMonth() .getDisplayName(TextStyle.FULL, Locale.ENGLISH) .toLowerCase() .contains("r"); } @Override public Collection<LocalDate> sortDates(List<LocalDate> unsortedDates) { return unsortedDates.stream() .sorted(Comparator.comparing(this::hasRInMonth, Comparator.reverseOrder()) .thenComparing((d1, d2) -> hasRInMonth(d1) ? d1.compareTo(d2) : d2.compareTo(d1))) .collect(Collectors.toList()); } }
3. 代码简化技巧
可以把Comparator逻辑进一步简化,直接结合naturalOrder()和reverseOrder():
@Override public Collection<LocalDate> sortDates(List<LocalDate> unsortedDates) { return unsortedDates.stream() .sorted(Comparator.comparing(this::hasRInMonth, Comparator.reverseOrder()) .thenComparing(date -> hasRInMonth(date) ? date : date, hasRInMonth(date) ? Comparator.naturalOrder() : Comparator.reverseOrder())) .collect(Collectors.toList()); }
关键优势
- 完全贴合需求定义,避免硬编码带来的逻辑偏差;
- 利用Java 8特性简化代码结构,可读性和可维护性更强;
- 单流处理流程,无需额外的列表拆分合并操作,代码更简洁。
内容的提问来源于stack exchange,提问作者Данил Денк
相关产品推荐
相关产品推荐

