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

如何使用Java Stream获取层级结构中的全量下属员工列表

实现前提

首先为Manager类添加subordinates的公共访问方法,避免直接暴露内部字段:

public List<Employee> getSubordinates() {
    // 返回不可变集合防止外部误改内部状态,不需要的话可以直接return subordinates;
    return Collections.unmodifiableList(subordinates);
}

方案1:Java 9+ 无递归写法(广度优先遍历)

直接在Manager类中添加获取所有下属的方法,不需要额外辅助函数:

import java.util.function.Function;
import java.util.stream.Stream;

public List<Employee> getAllSubordinates() {
    return Stream.iterate(
                    // 第一层:直接下属
                    getSubordinates().stream(),
                    // 每层递归取出下属中所有Manager的直接下属,作为下一层
                    currentLayer -> currentLayer
                            .filter(Manager.class::isInstance)
                            .map(Manager.class::cast)
                            .flatMap(Manager::getSubordinates)
            )
            // 直到某一层没有下属为止停止遍历
            .takeWhile(currentLayer -> currentLayer.findAny().isPresent())
            // 把所有层的员工合并成一个流
            .flatMap(Function.identity())
            // 可选:防止层级结构出现循环引用导致重复数据/死循环,正常树结构可省略
            .distinct()
            .toList();
}

方案2:Java 8兼容写法(深度优先遍历)

Java 8没有takeWhile方法,用递归实现层级展开:

import java.util.stream.Collectors;
import java.util.stream.Stream;

private Stream<Employee> flattenAllSubordinates(Employee employee) {
    if (employee instanceof Manager) {
        Manager manager = (Manager) employee;
        // 合并当前Manager的直接下属 + 所有下属的嵌套下属
        return Stream.concat(
                manager.getSubordinates().stream(),
                manager.getSubordinates().stream().flatMap(this::flattenAllSubordinates)
        );
    }
    // 普通员工没有下属,直接返回空流
    return Stream.empty();
}

public List<Employee> getAllSubordinates() {
    return flattenAllSubordinates(this)
            .distinct()
            .collect(Collectors.toList());
}

注意事项

  • 不建议将allSubordinates定义为固定的final成员变量:因为setManager方法会动态修改层级结构,固定字段会出现数据不一致的问题,每次调用方法动态计算更可靠。如果需要缓存结果,要在subordinates变更时清空缓存。
  • 如果你的业务场景可能出现循环层级(比如误将下属设为上级的上级),必须保留distinct(),或者额外通过员工ID的Set去重,避免死递归/重复数据。
  • 层级特别深的场景下,递归写法可能出现栈溢出,建议换成迭代版的广度优先遍历实现。

内容的提问来源于stack exchange,提问作者Artsiom Siarheyeu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:45:06