Erste Schritte Einträge aus verschachtelter Map chronoligisch ausgeben

PaulGustav

Mitglied
Hallo zusammen,

ich stehe da vor einem kleinen Problem, was der ein oder andere vllt schon einmal gelöst hat. Undzwar besitze ich Datensätze mit Zeitangaben. Zu jeder Zeitangabe / jedem Timestamp werden neue Attribute angegeben. Für die Auswertung dieser Daten ist es mir wichtig, dass ich die Attribute, mit denen die Timestamps nach und nach belegt wurden, gespeichert bzw auch in einer csv festgehalten werden. Ich habe meine Angelegenheit mal auf das folgende Minimalbespiel übertragen:

Java:
package Implements;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class CumulatedList {
   
   public static void main(String[] args) {
       Map<String,Integer> counter = new HashMap<>();
        TreeMap<Instant, Map<String,Integer>> tm = new TreeMap<Instant, Map<String,Integer>>();
        String s;;
        Instant year1 = Instant.parse("2015-01-01T20:00:00Z");
        Instant year2 = Instant.parse("2016-01-01T20:00:00Z");
        Instant year3 = Instant.parse("2017-01-01T20:00:00Z");
       
        //input i=0
        counter.put("Hunde", 1);
        counter.put("Katzen", 2);
        counter.put("Mäuse", 0);
        tm.put(year1, counter);
        System.out.println("Jahr 2015:");
        System.out.println("Hunde: " + counter.get("Hunde"));
        System.out.println("Katzen: " + counter.get("Katzen"));
        System.out.println("Mäuse: " + counter.get("Mäuse"));
        System.out.println("\n");
       
        //input i=1
        counter.put("Katzen", 3);
        tm.put(year2, counter);
        System.out.println("Jahr 2016:");
        System.out.println("Hunde: " + counter.get("Hunde"));
        System.out.println("Katzen: " + counter.get("Katzen"));
        System.out.println("Mäuse: " + counter.get("Mäuse"));
        System.out.println("\n");
       
        //input i=2
        counter.put("Kühe", 10);
        tm.put(year3, counter);
        System.out.println("Jahr 2017:");
        System.out.println("Hunde: " + counter.get("Hunde"));
        System.out.println("Katzen: " + counter.get("Katzen"));
        System.out.println("Mäuse: " + counter.get("Mäuse"));
        System.out.println("Kühe: " + counter.get("Kühe"));
        System.out.println("\n");
       
        writeList(tm,counter);       
    }

   private static void writeList(TreeMap<Instant, Map<String, Integer>> tm, Map<String,Integer> counter) {
       ArrayList<List<String>> list = new ArrayList<>();
       for(Map.Entry<Instant, Map<String,Integer>> outerMap : tm.entrySet()){
           for(Map.Entry<String, Integer> innerMap : outerMap.getValue().entrySet()){
               
           Instant timestamp = outerMap.getKey();
           String animal = innerMap.getKey();
           int value = innerMap.getValue();
           list.add(Arrays.asList(timestamp.toString(),animal, String.valueOf(value)));
           }
       }
       System.out.println("Chronik: " + "\n" + list);
   }

}

Als Ergbnis erhalte ich
Chronik:
[[2015-01-01T20:00:00Z, Mäuse, 0],
[2015-01-01T20:00:00Z, Kühe, 10],
[2015-01-01T20:00:00Z, Katzen, 3],
[2015-01-01T20:00:00Z, Hunde, 1],
[2016-01-01T20:00:00Z, Mäuse, 0],
[2016-01-01T20:00:00Z, Kühe, 10],
[2016-01-01T20:00:00Z, Katzen, 3],
[2016-01-01T20:00:00Z, Hunde, 1],
[2017-01-01T20:00:00Z, Mäuse, 0],
[2017-01-01T20:00:00Z, Kühe, 10],
[2017-01-01T20:00:00Z, Katzen, 3],
[2017-01-01T20:00:00Z, Hunde, 1]]

Gern würde ich erreichen, dass die Kühe im Jahr 2015 noch nicht erwähnt werden und das das Attribut für "Katzen" noch nicht zusammengerechnet wird.

Worin liegt mein Fehler?
 
Du brauchst für jedes Jahr einen neuen "counter". Aktuell fügst du dem tm dieselbe Instanz mehrfach hinzu. In der writeList-methode siehst du dann für the one and only tm Instanz nur den letzten Stand.
 
Ich habe leider einen Datensatz mit über 50k verschiedenen Timestamps. Und das wäre nur für ein Jahr.

Aber ja, dass nur die letzte Instanz gespeichert wird, habe ich schon irgendwie versucht zu umgehen. Am Besten wäre es doch sicherlich, wenn man seine Output-Datei, in diesem Fall die csv, immer wieder öffnen und eine neue Zeile hinzuschreiben würde. Meinst du das wäre okay. Ich gebe auch gerne ein Beispiel meiner Rohdaten.
 
Wie Harry Kane schon gesagt hat musst du für jedes Jahr eine neue Hashmap erzeugen!
Was du bis jetzt machst ist eine einzige HashMap verwenden, diese ständig zu erweitern und 3x zu deiner TreeMap hinzuzufügen (jeweils mit einem anderen Datum). Daher sind dann "plötzlich" auch 2015 schon Kühe da.

Du musst für jedes Jahr eine neue HashMap Instanz erzeugen:
Java:
.....
   public static void main(String[] args) {
       Map<String,Integer> counter;
....
        counter = new HashMap<>();
        //input i=0
        counter.put("Hunde", 1);
        counter.put("Katzen", 2);
        counter.put("Mäuse", 0);
        tm.put(year1, counter);
....
        counter = new HashMap<>();
        //input i=1
        counter.put("Katzen", 3);
        tm.put(year2, counter);
....
        counter = new HashMap<>();      
        //input i=2
        counter.put("Kühe", 10);
        tm.put(year3, counter);
....
 
Was der beste Weg ist, hängt davon ab, was du genau machen möchtest.
Zeige mal einen Ausschnitt aus deinen Rohdaten, und wohin du sie transformieren möchtest.
 
Vielen Dank für die Unterstützung. Leider habe ich erst jetzt gesehen, dass Harry Kane nochmal etwas gepostet hatte.
Ich habe mir die Arbeit nun ein wenig "erleichtert". Ich speichere nun die Attribute nicht mehr zu jedem einzelnem Zeitstempel, sondern habe mir eine Enum-Klasse gebaut, welche die die Datensätze entsprechend nach ihrem Zeitraum einordnet. Für meine Art von Analyse, brauche ich (vorerst) nur die Zeitscheiben Vormittags und Abends.
Die Lösung, die ich dafür gebaut habe, bedarf jedoch leider viel Rechenzeit. Ich werde dazu mal noch einen neuen Thread aufmachen.

Vielen Dank
 

Neue Themen


Zurück
Oben