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

Java递归填充ArrayList数据丢失问题(规避类级列表声明)

解决递归中列表重复初始化导致数据丢失的问题

我太懂你这个痛点了——每次递归都新建列表,之前攒的数据直接就没了,但又不想把列表放到类级别(毕竟类级别的变量搞不好会有线程安全或者状态污染的麻烦)。最靠谱的解决办法就是重载方法:对外暴露的方法负责初始化列表,内部的递归方法专门用来传递这个列表并填充数据。

具体代码可以这么改:

// 对外公开的方法,不用传列表,负责初始化
private List<MyClassType> getMyClassTypes(final String path) throws SVNException {
    List<MyClassType> myClassTypes = new ArrayList<>();
    // 调用内部递归方法,把刚初始化的列表传进去
    getMyClassTypesRecursive(path, myClassTypes);
    return myClassTypes;
}

// 内部递归方法,接收已有的列表,再也不重新初始化了
private void getMyClassTypesRecursive(final String path, List<MyClassType> myClassTypes) throws SVNException {
    // 这里写你原来的逻辑:获取当前path下的Collection,遍历处理
    Collection<?> entries = ...; // 你的SVN获取逻辑,比如svnClient.getEntries(path, ...)
    for (Object entry : entries) {
        // 如果是目录,继续递归
        if (isDirectory(entry)) { // 这里替换成你判断目录的逻辑,比如entry instanceof SVNDirEntry
            getMyClassTypesRecursive(getEntryFullPath(entry), myClassTypes);
        } else {
            // 如果是目标文件,创建MyClassType对象并加到列表里
            MyClassType type = buildMyClassTypeFromEntry(entry); // 替换成你的对象创建逻辑
            myClassTypes.add(type);
        }
    }
}

为什么这个方案好用?

  • 对外方法只初始化一次列表,递归全程都用同一个实例,所有递归调用都会往同一个列表里加数据,再也不会丢数据了。
  • 列表还是局部变量,只在对外方法的作用域里存在,完全避免了类级别变量可能带来的副作用(比如多线程调用时的并发问题)。
  • 代码结构也更清晰:对外方法管入口逻辑,内部方法专注递归遍历,职责分的明明白白。

要是你不想额外写个void方法,也可以让递归方法返回列表,每次递归时把当前列表传进去再返回(不过这种写法不如void方法直观):

private List<MyClassType> getMyClassTypes(final String path) throws SVNException {
    return getMyClassTypesRecursive(path, new ArrayList<>());
}

private List<MyClassType> getMyClassTypesRecursive(final String path, List<MyClassType> myClassTypes) throws SVNException {
    Collection<?> entries = ...; // 你的SVN获取逻辑
    for (Object entry : entries) {
        if (isDirectory(entry)) {
            getMyClassTypesRecursive(getEntryFullPath(entry), myClassTypes);
        } else {
            myClassTypes.add(buildMyClassTypeFromEntry(entry));
        }
    }
    return myClassTypes;
}

两种方式都能解决你的问题,个人更推荐第一种,因为void方法能更明确地表达“我就是要修改传入的列表”这个意图,别人看代码也能一眼明白。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:43:09