水仙花数是各位数字的n次方和等于自身的n位数;java 8中可用intstream.rangeclosed结合字符串拆分、map求幂与sum判断,如100~999内输出153、371、407。

水仙花数(Narcissistic Number)是指一个 n 位数,其各位数字的 n 次方之和等于它本身,比如 153 = 1³ + 5³ + 3³。Java 8 的 Stream 并不直接替代循环,而是提供声明式处理集合的方式;但“用 Stream 配合循环”这个说法容易引起误解——Stream 本身是函数式抽象,通常避免显式 for/while 循环。不过我们可以用 Stream 处理数字拆分与幂次求和,再结合传统循环遍历区间,实现更简洁、可读性更强的查找逻辑。
用 IntStream.range 查找指定范围内的水仙花数
不需要手动写 for (int i = start; i IntStream.rangeClosed(start, end) 生成闭区间整数流,再对每个数判断是否为水仙花数:
- 先将数字转为字符串获取位数 n
- 再用 String.chars() 或自定义拆位方式得到每位数字
- 对每位调用 Math.pow(digit, n),求和后与原数比较
用 Stream 拆解数字并计算 n 次幂和
例如判断 153 是否为水仙花数:
<font color="#666">int num = 153;
String s = String.valueOf(num);
int n = s.length();
int sum = s.chars()
.map(Character::getNumericValue)
.map(digit -> (int) Math.pow(digit, n))
.sum();
boolean isNarcissistic = sum == num;</font>
注意:Math.pow 返回 double,需强转 int;对大数(如 9 位以上)要小心精度问题,此时建议用 BigInteger.pow 或循环乘法代替。
完整示例:找出 100~999 内所有水仙花数
结合 Stream 流式判断 + 方法引用,代码清晰易维护:
<font color="#666">IntStream.rangeClosed(100, 999)
.filter(num -> {
String s = String.valueOf(num);
int n = s.length();
int sum = s.chars()
.map(Character::getNumericValue)
.map(digit -> (int) Math.pow(digit, n))
.sum();
return sum == num;
})
.forEach(System.out::println); // 输出:153, 371, 407</font>
注意事项与优化建议
- Stream 适合中等数据量;若遍历百万级数字,纯 for 循环 + 位运算(如 num % 10, num / 10)性能更高
- 避免在 filter 中重复计算位数或字符串转换,可提前提取或封装为工具方法
- 对 n > 6 的数,n 次幂增长极快,实际水仙花数非常稀少(如 10 位以内仅 88 个),可加范围剪枝
- 若需返回 List,用 .boxed().collect(Collectors.toList())
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











