JAVA:为什么我对Hashmap中特定键的ArrayList值的更新会改变所有其他键值?

JAVA:为什么我对Hashmap中特定键的ArrayList值的更新会改变所有其他键值?,java,arraylist,hashmap,Java,Arraylist,Hashmap,我需要你的帮助,因为我不知道为什么我在hashmap中更新一个值(对于一个特定的键)会改变几乎所有其他键的值。。。 以下是您可以尝试的相应代码: import edu.duke.*; import java.util.*; import java.io.*; public class WordsInFiles { private HashMap<String, ArrayList> map; public WordsInFiles(){ map =

我需要你的帮助,因为我不知道为什么我在hashmap中更新一个值(对于一个特定的键)会改变几乎所有其他键的值。。。 以下是您可以尝试的相应代码:

import edu.duke.*;
import java.util.*;
import java.io.*;

public class WordsInFiles {
    private HashMap<String, ArrayList> map;

    public WordsInFiles(){
        map = new HashMap<String, ArrayList>();
    }

    private void addWordsFromFile(File f) {
        FileResource fr = new FileResource(f);
        String fileName = f.getName();
        ArrayList<String> newWord = new ArrayList<String>();
        for (String s : fr.words()){
            if (!map.containsKey(s)) {
                newWord.clear();
                newWord.add(fileName);
                map.put(s, newWord);
                System.out.println("New:" + s + "\t" + newWord);
            } else {
                ArrayList<String> currArr = map.get(s);
                if (!currArr.contains(fileName)){
                    currArr.add(fileName);
                    newWord = currArr;
                    System.out.println("Update:" +s + "\t" + newWord);
                    map.put(s, newWord);
                }
            }
            System.out.println(map + "\n");
        }
    }

    public void tester() {
        System.out.println("\n ****** New Tester Instance ****** ");
        buildWordFileMap();
    }
}
我真的不明白为什么在“Update:are[brief1.txt,brief2.txt]”这行代码会为这个ArrayList值更新map的所有键。即使它会更新所有钥匙的价值:为什么除了狗之外所有的钥匙


提前感谢您的帮助

这是因为您一直在将相同的
ArrayList
实例放入映射中

之后

写:

newWord = new ArrayList<>();
或者,在一行中:

map.put(s, new ArrayList<>(Arrays.asList(fileName));
map.put(s,新的ArrayList(Arrays.asList(fileName));

但我建议你的“名单”实际上是
集合
s,因为只有当它们不存在时才添加它们。如果您想要保留顺序的集合,请使用
LinkedHashSet
作为您的值类型。

您创建了
新词
一次,然后继续将相同的
列表
放入
映射

ArrayList<String> newWord = new ArrayList<String>(); 
你可以把那条线换成

map.put(s, new ArrayList<>());
map.put(s,newarraylist());

1.正确

您在地图中输入的
newWord
始终是同一个实例,因此每个键都具有与值相同的
list
,您可以更改它并在任何地方看到它,每次都需要输入一个新的
list

for (String s : fr.words()){
    if (!map.containsKey(s)) {
        ArrayList<String> newWord = new ArrayList<>();         
        newWord.add(fileName);
        map.put(s, newWord);
    } else {
        ArrayList<String> currArr = map.get(s);
        if (!currArr.contains(fileName)){
            currArr.add(fileName);                            
        }
    }
}

因为您一直在将相同的
ArrayList
实例放入映射。ArrayList不是一直通过'ArrayList currArr=map.get(s);'更新吗?在接受之前查看所有答案;)我给了您一些改进代码的提示它工作了!谢谢你,安迪!我会接受答案,但我要等9分钟。。。非常感谢你的帮助!
ArrayList<String> newWord = new ArrayList<String>(); 
        if (!map.containsKey(s)) {
            newWord.clear();
            newWord.add(fileName);
            map.put(s, newWord); // your problem lies here
            // created just once but put in many times;
            System.out.println("New:" + s + "\t" + newWord);
        } 
map.put(s, new ArrayList<>());
for (String s : fr.words()){
    if (!map.containsKey(s)) {
        ArrayList<String> newWord = new ArrayList<>();         
        newWord.add(fileName);
        map.put(s, newWord);
    } else {
        ArrayList<String> currArr = map.get(s);
        if (!currArr.contains(fileName)){
            currArr.add(fileName);                            
        }
    }
}
// map is now a HashMap<String, Set<String>>
for (String s : fr.words()){
    map.computeIfAbsent(s, k -> new HashSet<>()).add(filename);
}