2017-06-13 48 views
4

想象一下,你有一個學生評估日記。每個學生在日記中都有一些標題。我想把這個存儲在HashMap<>,但我不知道爲什麼標記組合。java - 在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()); 
     } 
    } 
} 

在Main類

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]} 

我想不通我做錯了什麼。任何人都可以幫忙

+0

考慮使用來自Guava或Apache Commons的MultiMap。 –

回答

4

的問題是,你有你在你的外Map作爲值使用單個marks = new ArrayList<>();例如,你在所有你的內心Map價值觀使用,以及單journalContainer = new HashMap<>();實例。

我想刪除這兩個實例變量,而是使用局部變量。

你應該使用不同的ArrayList S和內HashMap S作爲您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); 
} 

順便說一句,這是沒有意義的,以有修改的靜態成員(在journalMap一個實例方法)。請使方法靜態,或使Map非靜態。

+0

對不起,這是我的錯''outputMarks()'。我編輯這個。恩典對你的幫助,你真棒 – phen0men

+0

我有一個問題。我怎樣才能從日誌中刪除商標?我只意識到按選定的值(例如5)刪除標記,但它出錯了,並刪除了具有選定值的所有標記。這是另一個問題,如果你能回答,我可以提出一個新問題 – phen0men

+1

@ phen0men你的意思是從某個特定學生和主題的ArrayList中刪除一個標記嗎?你可以通過索引來刪除它。 – Eran

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