如何将这段重叠区间删除代码转换为Java 8纯函数式风格?
将删除重叠区间的代码重写为Java 8函数式风格
你可以利用Java 8的Stream API和Lambda表达式,把原有的命令式代码转换为纯函数式风格。核心是用Stream.sorted替代数组排序,用Stream.reduce替代循环里的状态累积逻辑,具体实现如下:
简洁版(数组封装状态)
public int eraseOverlapIntervals(int[][] intervals) { if (intervals.length == 0) return 0; return intervals.length - Arrays.stream(intervals) .sorted(Comparator.comparingInt(a -> a[0])) .reduce(new int[]{intervals[0][1], 1}, (acc, next) -> { if (acc[0] <= next[0]) { return new int[]{next[1], acc[1] + 1}; } else { return acc[0] > next[1] ? new int[]{next[1], acc[1]} : acc; } }, (a, b) -> a)[1]; }
可读性优化版(自定义类封装状态)
如果觉得数组状态不够直观,可以用自定义类封装累积的状态:
private static class IntervalState { int currentEnd; int nonOverlapCount; IntervalState(int currentEnd, int nonOverlapCount) { this.currentEnd = currentEnd; this.nonOverlapCount = nonOverlapCount; } } public int eraseOverlapIntervals(int[][] intervals) { if (intervals.length == 0) return 0; return intervals.length - Arrays.stream(intervals) .sorted(Comparator.comparingInt(interval -> interval[0])) .reduce(new IntervalState(intervals[0][1], 1), (state, nextInterval) -> { if (state.currentEnd <= nextInterval[0]) { return new IntervalState(nextInterval[1], state.nonOverlapCount + 1); } else { return state.currentEnd > nextInterval[1] ? new IntervalState(nextInterval[1], state.nonOverlapCount) : state; } }, (s1, s2) -> s1).nonOverlapCount; }
逻辑说明
- 边界处理:先判断区间数组为空的情况,直接返回0,避免空指针异常。
- 排序:用
Stream.sorted(Comparator.comparingInt(...))替代原代码的Arrays.sort,按区间起始值升序排列。 - 状态累积:通过
reduce方法遍历流中的每个区间,维护两个核心状态:当前选中区间的结束值、最大不重叠区间的数量。累积逻辑完全对应原命令式循环的判断规则:- 若当前区间与下一个区间不重叠,更新结束值并增加计数
- 若重叠且下一个区间结束更早,替换当前结束值(为后续留出更多空间),计数保持不变
- 结果计算:用原区间总数减去最大不重叠区间数,得到需要删除的重叠区间数量。
内容的提问来源于stack exchange,提问作者curiousengineer
相关产品推荐
相关产品推荐

