2017-06-13 2 views
4

Stellen Sie sich vor, Sie haben ein Journal der Schülerbewertungen. Jeder Student hat einige Noten von jedem Fach in einer Zeitschrift. Ich möchte dies in HashMap<> speichern, aber ich kann nicht herausfinden, warum Marken kombinieren.Java - Inhalt entsprechende Daten in HashMap

In Journal Klasse:

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

In Hauptklasse:

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

So ist die Ausgabe:

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

Aber die richtige ausgegeben werden soll:

Ich kann nicht herausfinden, was ich falsch mache. Jeder kann helfen?

+0

Erwägen Sie die Verwendung von MultiMap von Guava oder Apache Commons. –

Antwort

4

Das Problem ist, dass Sie eine einzelne marks = new ArrayList<>(); Instanz haben, die Sie als Werte in allen inneren Map s verwenden, sowie eine einzelne journalContainer = new HashMap<>(); Instanz, die Sie als Werte in Ihrem äußeren Map verwenden.

Ich würde diese beiden Instanzvariablen entfernen und stattdessen lokale Variablen verwenden.

Sie sollten verschiedene ArrayList s und innere HashMap s als Werte Ihrer Map s verwenden:

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

BTW, macht es keinen Sinn machen, eine Instanz Methode zu haben, die ein statisches Element modifiziert (die journalMap). Machen Sie die Methode entweder statisch, oder machen Sie die Map nicht statisch.

+0

Sorry, das ist mein Fehler über 'outputMarks()'. Ich bearbeite das. Gnade für Sie für Ihre Hilfe, Sie sind fantastisch – phen0men

+0

Ich habe eine Frage. Wie kann ich die Markierung aus dem Journal entfernen? Ich erkannte nur, um die Markierung durch ausgewählten Wert (z. B. 5) zu löschen, aber es geht falsch und löscht alle Markierungen mit ausgewählten Wert. Dies ist eine andere Frage, und wenn Sie es beantworten können, kann ich eine neue Frage stellen – phen0men

+1

@ phen0men Sie meinen, eine Markierung von der ArrayList eines bestimmten Studenten und eines Themas zu entfernen? Sie können es nach seinem Index entfernen. – Eran

0

Wenn Sie eine neue Markierung hinzufügen, wird die Arraylist bereits im Speicher zugewiesen, bald wird es alle Werte, die Sie bereits unabhängig von dem

Das Thema gesetzt haben, bevor Sie eine Validierung vornehmen werden:

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