java - HashMap中的内容适当数据

时间:2017-06-13 12:54:58

标签: java collections

想象一下,你有一份学生评估期刊。每个学生在期刊中都有一些每个科目的分数。我希望将其存储在HashMap<>中,但我无法弄清楚为什么标记会合并。

在期刊课

public class Journal {
    private static HashMap<String, HashMap<String, ArrayList<Integer>>> journal = new HashMap<>(); // "Student" -> "Subject", mark[]

    private HashMap<String, ArrayList<Integer>> journalContainer = new HashMap<>();
    private ArrayList<Integer> marks = new ArrayList<>();

    public void addMark(String student, String subject, int mark) {
        marks.add(mark);
        journalContainer.put(subject, mark);
        journal.put(student, journalContainer);
    }

    public static void outputMarks() {
        for(HashMap.Entry<String, HashMap<String, ArrayList<Integer>>> entry : journal.entrySet())
        {
            System.out.println(entry.getKey() + "/" + entry.getValue());
        }
    }
}

在主要课程中

public class Main {
    public static void main(String[] argc) {
        getJournal().addMark("Alex", "math", 4); // name, subject, mark
        getJournal().addMark("Alex", "math", 2);
        getJournal().addMark("George", "english", 2);
        getJournal().addMark("George", "english", 2);

        Journal.outputMarks();
    }
}

所以输出是:

Alex/{english=[4, 2, 2, 2], math=[4, 2, 2, 2]}
George/{english=[4, 2, 2, 2], math=[4, 2, 2, 2]}

但正确的输出应该是:

Alex/{math=[4, 2]}
George/{english=[2, 2]}

我无法弄清楚我做错了什么。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:4)

问题是您有一个marks = new ArrayList<>();实例,您在所有内部Map中使用该实例,以及您用作值的单个journalContainer = new HashMap<>();实例你的外Map

我会删除这两个实例变量,而是使用局部变量。

您应该使用不同的ArrayList和内部HashMap作为Map s的值:

public void addMark(String student, String subject, int mark) {
    HashMap<String, ArrayList<Integer>> journalContainer = journal.get(student);
    if (journalContainer == null) {
        journalContainer = new HashMap<>();
        journal.put(student,journalContainer);
    }
    ArrayList<Integer> marks = journalContainer.get(subject);
    if (marks == null) {
        marks = new ArrayList<>();
        journalContainer.put(subject, marks);
    }
    marks.add(mark);
}
顺便说一句,拥有一个修改静态成员的实例方法(journal Map)是没有意义的。要么使方法成为静态,要么使Map非静态。

答案 1 :(得分:0)

当您添加新标记时,ArrayList已经在内存中分配,很快它将获得您已经放置的所有值,而不管主题是什么

在此之前,您将进行验证:

public void addMark(String student, String subject, int mark) {
    marks.add(mark);
    journalContainer.put(subject, mark);
    journal.put(student, journalContainer);

    HashMap<String, ArrayList<Integer>> journalContainer = journal.get(student);

    if(journalContainer == null) {
        HashMap<String, ArrayList<Integer>> journalContainer = new HashMap<>();
    }

    ArrayList<Integer> marks = journalContainer.get(subject);

    if(marks == null) {
        marks = journalContainer.get(subject);
    }  

    marks.add(mark);
    journalContainer.put(subject, mark);
    journal.put(student, journalContainer);
}