You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

我可以这样使用lambda函数统计树节点数量吗?附AtomicInteger疑问

代码问题修正

你当前实现的size方法存在逻辑错误:当前仅累加了所有子树的节点数,没有计入当前节点本身,非叶子节点的返回值需要额外加1,修正后代码如下:

/** = the number of nodes in this H1N1Tree.
 * Note: If this is a leaf, the size is 1 (just the root) */
public int size() {
    // TODO 2. This method must be recursive.
    if (children.size() == 0) return 1;
    AtomicInteger sizeOfChildren = new AtomicInteger();
    children.forEach(p -> {sizeOfChildren.addAndGet(p.size());});
    // 加上当前节点本身的计数
    return 1 + sizeOfChildren.get();
}

如果追求更简洁的写法,也可以直接用Stream流完成累加,不需要手动声明计数器:

public int size() {
    return 1 + children.stream().mapToInt(H1N1Tree::size).sum();
}

关于AtomicInteger用法的疑问解答

你的理解是对的,这里AtomicInteger的用法和C++中传入int指针的作用高度类似:

  • Java lambda对外部局部变量的捕获有严格限制:只能捕获*不可变(final或effectively final)*的变量。如果直接声明普通int sizeOfChildren,lambda捕获的是int的值,且不允许在lambda内部修改该值,编译会直接报错。
  • 你用AtomicInteger的本质是捕获了这个对象的不可变引用,虽然引用本身不能改,但可以调用对象的方法修改其内部存储的整数值,这和C++里lambda捕获int指针、指针本身不变但可以通过指针修改指向的int值的逻辑是完全一致的。

补充说明:如果只是单线程场景下用lambda做累加,不需要并发安全的话,用长度为1的int数组int[] sizeOfChildren = new int[1];也能实现同样效果,原理也是捕获不可变的数组引用、修改数组内部的元素值,只是AtomicInteger的API更友好。


内容的提问来源于stack exchange,提问作者James E

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 23:36:03