javahashmap将值存储在非预期的键中

myzjeezk  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(394)

我正在做一个程序,告诉你一个包的信息。但是,我在反向依赖项方面遇到了一些问题(请参见下面的注解:检查以前的反向依赖项并保存它们)。主要问题是,在打印时,在将值放入hashmap之后,它似乎以正确的方式存储它们。不过,在完成该过程后打印Map的键和值会返回其他值。编码后可以看到打印的信息。

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) {
                //System.out.println(line);

                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>();
                    ArrayList<String> currentRevDependencies = new ArrayList<String>();
                    String currentDependency;

                    for (String dependencyWithVersion : dependenciesWithVersion) {
                        int index = dependencyWithVersion.indexOf("(");
                        currentRevDependencies.clear();

                        //Take the version out of the package name
                        if (index != -1) {
                            currentDependency = dependencyWithVersion.substring(0, index);
                        } else {
                            currentDependency = dependencyWithVersion;
                        }
                        currentDependency.trim();
                        dependenciesWOVersion.add(currentDependency);

                        //Check for previous reverse dependencies and save them
                        if (revDependencies.get(currentDependency) != null){
                            currentRevDependencies = revDependencies.get(currentDependency);
                        }

                        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");
        }

   }
}

屏幕上打印以下内容:

Package: accountsservice Dependency:  dbus RevDepencencies: [accountsservice]
Package: accountsservice Dependency: libaccountsservice0  RevDepencencies: [accountsservice]
Package: accountsservice Dependency: libc6  RevDepencencies: [accountsservice]
Package: accountsservice Dependency: libglib2.0-0  RevDepencencies: [accountsservice]
Package: accountsservice Dependency: libpolkit-gobject-1-0  RevDepencencies: [accountsservice]
Package: acl Dependency:  libacl1  RevDepencencies: [acl]
Package: acl Dependency: libc6  RevDepencencies: [accountsservice, acl]
Package: acpi-support Dependency:  acpid  RevDepencencies: [acpi-support]

acpid  [acpi-support]
libaccountsservice0  [accountsservice, acl]
libpolkit-gobject-1-0  [accountsservice, acl]
libglib2.0-0  [accountsservice, acl]
libc6  [accountsservice, acl]
dbus [accountsservice, acl]
libacl1  []

似乎存储的值不是进程结束时打印的值。

ljo96ir5

ljo96ir51#

问题

java按值传递对象引用。当你把
List currentRevDependencies 进入你的
revDependencies Map ,存储在 Map 不是 List 但仅仅是一个对象引用。什么时候 currentRevDependencies 外部发生变化(如您呼叫 clear 在上面),Map中的列表会改变。这意味着对于while循环的一次迭代中添加的所有键 List 引用将是相同的,从而导致观察到的值重复。

如何修复

若要解决此问题,请创建新的 List 对于放入 Map 而不是清除最后一个 Map 每次都是这样:

//[...]
String subline = line.substring(dependenciesStart.length());
String[] dependenciesWithVersion = subline.split(", ");
ArrayList<String> dependenciesWOVersion = new ArrayList<String>();
String currentDependency;

for (String dependencyWithVersion : dependenciesWithVersion) {
    ArrayList<String> currentRevDependencies = new ArrayList<String>(); // <- instantiate new list each iteration

    //[...]

    revDependencies.put(currentDependency, currentRevDependencies);
}
dependencies.put(packageName, dependenciesWOVersion);
//[...]

输出:

Package: libasan0 Dependency:  gcc-4.8-base  RevDepencencies: [libasan0]
Package: libasan0 Dependency: libc6  RevDepencencies: [libasan0]
Package: libasan0 Dependency: libgcc1  RevDepencencies: [libasan0]
Package: libasan0 Dependency: libstdc++6  RevDepencencies: [libasan0]
Package: libvorbisfile3 Dependency:  libc6  RevDepencencies: [libvorbisfile3]
Package: libvorbisfile3 Dependency: libogg0  RevDepencencies: [libvorbisfile3]
Package: libvorbisfile3 Dependency: libvorbis0a  RevDepencencies: [libvorbisfile3]
Package: libquadmath0 Dependency:  gcc-4.9-base  RevDepencencies: [libquadmath0]
Package: libquadmath0 Dependency: libc6  RevDepencencies: [libasan0, libquadmath0]
 libc6  [libvorbisfile3]
libvorbis0a  [libvorbisfile3]
 gcc-4.9-base  [libquadmath0]
libgcc1  [libasan0]
libc6  [libasan0, libquadmath0]
libstdc++6  [libasan0]
 gcc-4.8-base  [libasan0]
libogg0  [libvorbisfile3]

相关问题