Hasmap aufüllen

Status
Nicht offen für weitere Antworten.

iceT18

Mitglied
Hallo,

Hab ein kleines Problem, von dem ich nicht so richtig weis, wie es gelöst werden könnte. Vielleicht kann mir wer helfen!

Ich habe eine Hash-Map die folgendermaßen aussieht:
--------------------------------------------------------------------
1;'Film1';'2004';2004;34637;'Azaria, Hank'
2;'Film2';'2004-????';2004-????;819279;'Zucker, Adam (II)'
3;'Film3';'2006';2006;
4;'Film4';'????';????;1026855;'Ittleson, Stephanie'
--------------------------------------------------------------------
1...4 ist der key

Das Problem ist Zeile 3, ich muss schauen, dass die Haspmap immer komplett befüllt ist!!!

Also, so müsste die Zeile 3 richtig lauten:
3;'Film3';'2006';2006;" ";''

Wie geh ich die Hashmap durch und befülle die leeren Felder?

Mein Java code für die ausgabe sieht folgendermaßen aus: (out.write, damit schreib ich in ein csv file):
Code:
            String help = null;
            String value = null;
            for(int i =1; i<=movies.size();i++){
              help = Integer.toString(i);
              value = movies.get(help).toString();
              value = i+";"+value+"\n";
              out.write(value);
            }
Danke für eure Hilfe!
mfg
iceT
 

Rydl

Bekanntes Mitglied
ich würd an deiner stelle eine klasse film schreiben, die die ganzen werte speichert, also filmname, jahr und was du da so hast. dann überschreibst du am besten die toString() methode von deiner filmklasse und gibst damit einen string zurück, der sich aus den werten der members deiner filmklasse zusammensetzt, etwa so:

return film + "," + jahr + "," + regisseur + "\n";

dann erstellst du eine HashMap<String, FilmObjekt> und dann sollte das auslesen und reinschreiben auch etwas einfacher funktionieren:

Code:
HashMap<String, FilmObjekt> movies = new HashMap<String, FilmObjekt>();
movies.put("1", new FilmObjekt("Film1", "2005", "", "", ""));
// usw...

Set<String> keys = movies.keySet();
for (String key : keys) {
	out.write(key + "," + movies.get(key).toString();
}
 

iceT18

Mitglied
Das ganze ist leider etwas komplizierter....

Ich kann mir nicht aussuchen, wie ich die HashMap befülle, ich bekomme die Datensätze direkt aus einer MySQL Datenbank übergeben. Dazu gibt es 5 Methoden, die mit 7 MySQL-Abfragen die Ergebnisse liefern.

Deshalb muss ich unbedingt die Hashmap erst zum Schluss durchgeben, wenn sie durch die MySQL Abfragen fertig zusammmengebaut wurde.
Ich will die fehlenden Datensätze einfach durch " " in der HashMap ersetzen.

Danke
mfg
IceT
 

Rydl

Bekanntes Mitglied
iceT18 hat gesagt.:
Ich kann mir nicht aussuchen, wie ich die HashMap befülle, ich bekomme die Datensätze direkt aus einer MySQL Datenbank übergeben. Dazu gibt es 5 Methoden, die mit 7 MySQL-Abfragen die Ergebnisse liefern.

du kannst diese 5 methoden nicht manipulieren und die map die dabei rauskommt hat immer strings als werte? falls du diese methoden doch verändern durftest, poste sie doch mal hier, vielleicht kann man dir helfen deine ergebnis map etwas ausgabefreundlicher zu generieren...
 

moormaster

Top Contributor
iceT18 hat gesagt.:
Ich will die fehlenden Datensätze einfach durch " " in der HashMap ersetzen.

Ich dachte das Problem ist, dass in den Datensätzen nicht alle Attribute einen Wert haben? Von fehlenden Datensätzen war doch erstmal gar nicht die Rede?

Vielleicht erklärst du mal, was du genau mit den Strings der Form
"Attr1;Attr2;...;...;Attrn" vor hast, dass du die leeren Attribute meinst auffüllen zu müssen. Evtl. gibt es ja auch bessere Lösungen?
 

iceT18

Mitglied
Code:
 public void setMovies() {
        Statement my_stmt2 = null;
        try {
            my_stmt2 = conn.createStatement();
            ResultSet my_result2;
            String sql = "SELECT movieid,title FROM movies LIMIT "+txt_int;
            my_result2 = my_stmt2.executeQuery(sql);

            while (my_result2.next()) {
                String mid = my_result2.getString("movieid");
                String title = my_result2.getString("title");

                movies.put(mid, "'"+title+"'");

            }
        } catch (SQLException ex) {
        }
    }



public void setActor() {
            Statement my_stmt2 = null;
            try {
                my_stmt2 = conn.createStatement();
                ResultSet my_result2;
                String sql2 = "SELECT SQL_BIG_RESULT erg1.movieid, actors.actorid, actors.name FROM actors JOIN (    
SELECT movies.movieid, movies2actors.actorid FROM movies, movies2actors WHERE movies.movieid = 
movies2actors.movieid ) AS erg1 ON actors.actorid = erg1.actorid GROUP BY erg1.movieid LIMIT "+txt_int;
                my_result2 = my_stmt2.executeQuery(sql2);
                String value = null;
                while (my_result2.next()) {
                    String mid4 = my_result2.getString("movieid");
                    String aid = my_result2.getString("actorid");
                    String aname= my_result2.getString("name");

                    if(movies.containsKey(mid4))
                    {
                    value = movies.get(mid4).toString();
                    value = value + ";" +aid+";"+"'"+aname+"'";
                    movies.put(mid4, value);

                    }

                }
            } catch (SQLException ex) {
            }
            //System.out.println(movies.entrySet().toString());
    }

Das ist meine Methoden um die MovieID zu schreiben und die actor zu finden, Ich bekomme die MovieID,ActorID und den Namen des Actos. D.h Ich muss jeweils die richtige MovieID finden, und den Actos mit ID in die Hashmap an die richtige Stelle schreiben.

Nur, da gibt es dann noch die Producer, das Genre,..... Die MovieID und der Title stehen immer in der Hashmap, die restlichen, z.b Producer werden mittels Checkboxes gewählt und nur dann in die HashMap geschrieben.

@moormaster

Ich muss eine fertige MovieDatabase visualisieren, und diese fast über 12 Mio Einträge! Die Visualisierung ist bereits ein fertiges Projekt, ich muss nur noch die Daten liefern. Und dazu darf in der HashMap kein leeres Feld bleiben. Leerzeichen geht aber, hab ich getestet.

mfg
IceT
 

moormaster

Top Contributor
Nun frage ich mich aber, wieso du dir es nicht aussuchen kannst, wie du die Hash-Map befüllst?

In der Methode setMovies bereitest du deine Hashmap momentan vor, indem du alle Movie IDs mit Titel einträgst.
Danach hängt setActor() an die jeweiligen Datensätze noch zusätzliche Informationen an (ActorID und ActorName).

Was spräche denn nun dagegen, das ganze nicht als String bestehend aus Attributen, die durch ; getrennt werden, zu speichern, sondern als Objekt?

setMovies würde in der Hashmap zunächst alle Objekte anlegen, in denen dann jedes Attribut erstmal auf "" gesetzt wird (bis auf den Filmtitel).

setActors würde dann so verfahren, dass es sich das jeweilge Filmobjekt aus der Hashmap holt und dort die Eigenschaften für Actor ID und ActorName ändert.

Eine geeignete toString-Methode dieses Objekts (wie oben schon von Rydl erklärt) würde dir die Zeilen in der gewünschten Form liefern.

Edit:

Angesichts der Tatsache, dass es sich um 12 Mio Einträge handeln wird, ist das definitiv eine bessere Lösung, als nach dem Erstellen der Hashmap nochmal alle Einträge durchzugehen und die Trennzeichen ( ; ) zu zählen.
 

iceT18

Mitglied
Ja, die Darstellung von oben ist nicht ganz richtig, ist eigentlich schon mein CSV File.

So schaut meine HashMap Z.B. aus:

[3='"#1 Single" (2006)';'2006';2006;1019781;'Howell, Vickie',
5='"#1 Single" (2006) {Finishing a Chapter (#1.5)}';'????';????,
2='"#1 College Sports Show, The" (2004)';'2004-????';2004-????;819279;'Zucker, Adam (II)',
4='"#1 Single" (2006) {Cats and Dogs (#1.4)}';'????';????;1026855;'Ittleson, Stephanie',
1='!Huff (2004) (TV)';'2004';2004;34637;'Azaria, Hank']

Das Problem ist, meine meine Java Kenntnisse nicht ausreichen, um das was du vorgeschlagen hast umzusetzten.

P.S. ich filter die 12 Mio Einträge sowieso schon mit LIMIT und spezielen Abfragen, also viel länger wie das Bsp oben ist die HashMap sowieso nicht.

iceT
 

moormaster

Top Contributor
Eine Alternative wäre doch auch, die SQL Daten nicht mehrstufifg abzufragen:

Du holst dir momentan erst die Movie IDs und die Titel und dann in einer weiteren Abfrage erst die ActorID und ActorName...

Sowas kann man doch auch in eine einzige SQL Abfrage verpacken, so dass die Ergebnisrelation gleich alle Daten beinhaltet, die in deine CVS-Datei rein sollen.

SELECT * FROM movies LEFT JOIN { SELECT * FROM movies2actors,actors WHERE actors.actorid == movies2actors.actorid } AS erg1 ON erg1.movieid == movies.movieid

Dann sollte sich doch eine Relation ergeben, die Prinzipiell alle Filme beinhaltet und zusätzlich, wo Informationen existieren, auch noch Infos über Actor.

Dort würden fehlende Werte doch automatisch NULL werden. Dann müsste man NULL nur noch durch einen leeren String ersetzen und hätte in jedem Datensatz immer die gleiche Anzahl von Attributen zur Verfügung, womit man direkt jede Zeile der CVS Datei zusammenbasteln kann, ohne dass es zuwenig Trennzeichen gibt.
 

iceT18

Mitglied
Geht leider auch nicht, so hab ichs nämlich früher gehabt.
Weil bei einer großen Abfrage und 12 Millionen Einträgen reichen 2GB Arbeitsspeicher nicht aus! Das schafft der pc nicht! Deshalb war ich gezwungen, die Abfragen auf mehrere Etappen aufzuteilen.

mfg
iceT
 

moormaster

Top Contributor
Und wenn du das Etappenweise abfragst, indem du Bedingungen an die Movie-ID stellst?

Meinetwegen zuerst alle Einträge mit Movie ID zwischen 0 und 1000, dann zwischen 1001 und 2000 usw?
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben