插入 HashMap 会更改地图中每个键的值 [重复]

Posted

技术标签:

【中文标题】插入 HashMap 会更改地图中每个键的值 [重复]【英文标题】:Inserting into a HashMap changes the values of every key in the map [duplicate] 【发布时间】:2022-01-21 04:46:13 【问题描述】:

尝试为和弦进行制作一个简单的马尔可夫链。在内容只是“I IV V”(没有换行符或其他任何内容)的文本文件上测试它。

我创建了一个HashMap<String, ArrayList<String>> 并使用七个和弦值作为键填充它,并使用 I 和 V 作为值。打印出来就可以了……

ii [I, V]
vi [I, V]
V [I, V]
vii [I, V]
iii [I, V]
I [I, V]
IV [I, V]

它在“I IV V”行中毫无问题地读取...

Chord: I
Adding IV to I\'s list
Existing values array:
I
V
Updated values array:
I
V
IV
Updated hashtable entry:
[I, V, IV]

到目前为止,一切看起来都很好。但是,当我在此之后打印出 HashMap 时:

Full hashmap:
ii [I, V, IV]
vi [I, V, IV]
V [I, V, IV]
vii [I, V, IV]
iii [I, V, IV]
I [I, V, IV]
IV [I, V, IV]

当我只想更新“I”的条目时,它显然改变了映射中每个键的值(其他六个键仍应映射到 [I, V])。我知道循环不会使这成为世界上最简单的工作,但是我遍历了所有循环,但我仍然不确定它为什么会这样。想法?

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class Chords 
    private String[] options = new String[]"I", "ii", "iii", "IV", "V", "vi", "vii";
    private HashMap<String, ArrayList<String>> chords = new HashMap<>();


    public static void main(String[] args) throws FileNotFoundException 
        Chords generator = new Chords("data.txt");
    


    public Chords(String filename) throws FileNotFoundException 
        this.chords = new HashMap<>();
        ArrayList<String> tonic = new ArrayList<>();
        tonic.add("I");
        tonic.add("V");
        for(int i=0; i<options.length; i++) 
            chords.put(options[i], tonic);
        

        System.out.println("Initial hashmap:");
        for (String str : chords.keySet()) 
            String value = chords.get(str).toString();
            System.out.println(str + " " + value);
        

        Scanner myScanner = new Scanner(new File(filename));
        ArrayList<String> temp = new ArrayList<>();


        // read in the data
        while(myScanner.hasNextLine()) 
            System.out.println("\n\nNEW LINE:");
            String sInput = myScanner.nextLine();
            System.out.println(sInput);
            String[] ch = sInput.split(" ");

            // read each line and parse out the chords that follow each one
            for(int i=0; i<ch.length-1; i++) 
                System.out.println("Now looking at chord: " + ch[i]);
                System.out.println("Adding " + ch[i+1] + " to " + ch[i] + "\'s list of following chords");

                temp = chords.get(ch[i]); // retrieve the existing ArrayList of values. We know this is non-null because we pre-populated the HashMap above.

                System.out.println("Existing values array:");
                for(String str : chords.get(ch[i])) 
                    System.out.println(str);
                

                temp.add(ch[i+1]); // add the subsequent chord from this data file

                System.out.println("Updated values array:");
                for(String str : temp) 
                    System.out.println(str);
                

                chords.put(ch[i], temp); // update/overwrite the value array for the given chord

                System.out.println("Updated hashtable entry:");
                System.out.println(chords.get(ch[i]));

                System.out.println("Full hashmap:");
                for (String str : chords.keySet()) 
                    String value = chords.get(str).toString();
                    System.out.println(str + " " + value);
                
                temp.clear();
            
        

        for (String str : chords.keySet()) 
            String value = chords.get(str).toString();
            System.out.println(str + " " + value);
        
    

【问题讨论】:

【参考方案1】:

原因是地图中的所有键都映射到一个值(列表)。因此,您所做的所有更改都在同一个列表中进行。

ArrayList<String> tonic = new ArrayList<>();
for(int i=0; i<options.length; i++) 
  chords.put(options[i], tonic);  <<== tonic 

您可以执行以下操作:为每个键创建一个新列表。

for(int i=0; i<options.length; i++) 
  chords.put(options[i], new ArrayList<String>());   

【讨论】:

以上是关于插入 HashMap 会更改地图中每个键的值 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 流构建器概念

如何从scala中的地图更改键

Java HashMap原理

更改列表中每个字典的特定键的值 - python

在 Java 的 HashMap 中查找键的值

更新HashMap中指定键的值