Java 8遍历现有Stream时如何基于条件动态生成整数流完成序列求和统计
实现方案:Java 8 Stream API 完成连续序列求和计数
需求拆解
- 输入为1~n的连续正整数流,n最大可到Long类型最大值,必须惰性处理不能全量加载
- 对每个起始值
start,生成从start开始的连续数前缀和序列,一旦和 >= 目标值就停止计算 - 统计最终和等于目标值的序列总个数
注意:Java 8 原生Stream没有
takeWhile(Java 9新增)操作实现提前截断,我们可以基于连续正整数和严格递增的特性来实现终止逻辑,避免无效计算。
方案1:原生API实现(无额外依赖)
外层用Stream遍历起始值,内层利用和的递增特性提前终止计算,性能最优:
import java.util.stream.LongStream; public class SequenceSumCounter { public static long countValidSequences(long maxN, long targetSum) { return LongStream.rangeClosed(1, maxN) // 过滤符合条件的序列起始值 .filter(start -> { long currentSum = 0; for (long i = start; i <= maxN; i++) { currentSum += i; if (currentSum == targetSum) return true; // 正整数和严格递增,超过目标值直接终止 if (currentSum > targetSum) return false; } return false; }) // 符合条件的起始值数量就是序列总个数 .count(); } public static void main(String[] args) { // 示例测试:n=10,目标和15,预期输出3 // 符合条件的序列:[1,2,3,4,5]、[4,5,6]、[7,8] System.out.println(countValidSequences(10, 15)); } }
方案2:纯Stream函数式实现
自定义工具方法模拟takeWhile能力,完全用Stream操作实现逻辑:
import java.util.Spliterators; import java.util.function.Predicate; import java.util.stream.LongStream; import java.util.stream.StreamSupport; public class PureStreamImpl { // 模拟Java9+的takeWhile操作 private static LongStream takeWhile(LongStream stream, Predicate<Long> predicate) { return StreamSupport.longStream( new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE, 0) { final java.util.PrimitiveIterator.OfLong iterator = stream.iterator(); @Override public boolean tryAdvance(java.util.function.LongConsumer action) { if (iterator.hasNext()) { long val = iterator.nextLong(); if (predicate.test(val)) { action.accept(val); return true; } } return false; } }, false ); } public static long countValidSequences(long maxN, long targetSum) { return LongStream.rangeClosed(1, maxN) .filter(start -> { final long[] sumHolder = {0}; // 截断到和超过目标值为止 long count = takeWhile(LongStream.rangeClosed(start, maxN), i -> { sumHolder[0] += i; return sumHolder[0] <= targetSum; }).count(); return count > 0 && sumHolder[0] == targetSum; }) .count(); } public static void main(String[] args) { System.out.println(countValidSequences(10, 15)); // 输出3 } }
内容的提问来源于stack exchange,提问作者springbootlearner
相关产品推荐
相关产品推荐

