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

Java HashMap处理包反向依赖时存储值与读取结果不一致问题

修复HashMap存储反向依赖的异常问题

我看了你的代码和运行结果,问题出在复用同一个ArrayList对象导致的引用混乱,这是Java里引用类型常见的坑。

问题根源分析

  1. 你在处理依赖的for循环外面创建了currentRevDependencies这个ArrayList,所有依赖的反向依赖处理都共用这个对象的引用。
  2. 每次循环里的currentRevDependencies.clear()会直接清空这个对象的内容——如果这个对象已经被存入revDependencies的多个键下,这些键对应的列表都会被同步清空。
  3. 比如你处理完acl的libacl1依赖后,这个对象被存入revDependencies的libacl1键;之后处理acpi-support的acpid依赖时,你先clear了这个对象,再把它存入acpid键,这就导致libacl1对应的列表也被清空了。
  4. 还有个小细节:currentDependency.trim()没有赋值给变量,String是不可变类型,这个调用不会改变原字符串,等于无效操作。

解决方案

每次处理单个依赖时,要么从revDependencies获取已有的反向依赖列表,要么新建一个全新的ArrayList,不要复用外部的对象。修改后的核心代码片段如下:

// 移除循环外的currentRevDependencies定义
String currentDependency;
for (String dependencyWithVersion : dependenciesWithVersion) {
    int index = dependencyWithVersion.indexOf("(");
    // 修复trim()的赋值问题:String不可变,必须接收返回值
    if (index != -1) {
        currentDependency = dependencyWithVersion.substring(0, index).trim();
    } else {
        currentDependency = dependencyWithVersion.trim();
    }
    dependenciesWOVersion.add(currentDependency);
    
    // 正确获取或新建反向依赖列表,避免复用同一对象
    ArrayList<String> currentRevDependencies = revDependencies.get(currentDependency);
    if (currentRevDependencies == null) {
        currentRevDependencies = new ArrayList<>();
    }
    currentRevDependencies.add(packageName);
    revDependencies.put(currentDependency, currentRevDependencies);
    
    System.out.print("Package: " + packageName + " Dependency: " + currentDependency + " RevDepencencies: " + revDependencies.get(currentDependency) + "\n");
}

完整修复后代码

public class MainActivity {
    public static void main (String[] args) {
        ArrayList<String> packages = new ArrayList<String>();
        ArrayList<String> descriptions = new ArrayList<String>();
        HashMap<String, ArrayList<String>> dependencies = new HashMap<>();
        HashMap<String, ArrayList<String>> revDependencies = new HashMap<>();
        int i = 0;
        String packageStart = "Package:";
        String descriptionStart = "Description:";
        String dependenciesStart = "Depends:";
        String packageName = "";
        BufferedReader reader;
        try {
            reader = new BufferedReader(new FileReader( "/var/lib/dpkg/status"));
            String line = reader.readLine();
            while (line != null) {
                if (line.startsWith(packageStart)) {
                    packageName = line.substring(packageStart.length()).trim();
                    packages.add(packageName);
                }
                if (line.startsWith(descriptionStart)) {
                    descriptions.add(line.substring(descriptionStart.length()).trim());
                }
                if (line.startsWith(dependenciesStart)) {
                    String subline = line.substring(dependenciesStart.length());
                    String[] dependenciesWithVersion = subline.split(", ");
                    ArrayList<String> dependenciesWOVersion = new ArrayList<String>();
                    
                    String currentDependency;
                    for (String dependencyWithVersion : dependenciesWithVersion) {
                        int index = dependencyWithVersion.indexOf("(");
                        // 修复trim()的赋值问题
                        if (index != -1) {
                            currentDependency = dependencyWithVersion.substring(0, index).trim();
                        } else {
                            currentDependency = dependencyWithVersion.trim();
                        }
                        dependenciesWOVersion.add(currentDependency);
                        
                        // 正确获取或新建反向依赖列表
                        ArrayList<String> currentRevDependencies = revDependencies.get(currentDependency);
                        if (currentRevDependencies == null) {
                            currentRevDependencies = new ArrayList<>();
                        }
                        currentRevDependencies.add(packageName);
                        revDependencies.put(currentDependency, currentRevDependencies);
                        
                        System.out.print("Package: " + packageName + " Dependency: " + currentDependency + " RevDepencencies: " + revDependencies.get(currentDependency) + "\n");
                    }
                    dependencies.put(packageName, dependenciesWOVersion);
                    if (i == 2){
                        break;
                    }
                    i++;
                }
                line = reader.readLine();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        for (String key : revDependencies.keySet()){
            System.out.print(key + " " + revDependencies.get(key) + "\n");
        }
    }
}

修复后效果

修改后,每个反向依赖列表都是独立的对象,不会出现修改一个列表影响其他键的情况。最后遍历revDependencies时,每个键对应的列表都会和你即时打印的结果一致,比如libacl1会显示[acl],dbus显示[accountsservice],libc6显示[accountsservice, acl],完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 22:22:50