Durchlaufen von Hashmap und Arraylist

Burned

Mitglied
Hallo zusammen,

ich habe eine Map<Integer, List<Integer>>, in der jede List das Alter einer Person und die Altersspanne enthält, in der sie sich einen Partner sucht.
Diese Hashmap versuche ich so zu filtern, dass ich die für die einzelnen Alter an eine andere Methode übergebe, die dann anhand des alters und der Spanne einen passenden Partner aussucht. Ich bin mir aber nicht sicher, ob ich die Map und die List sauber durchlaufe, da ich mit beiden noch nicht viel gemacht habe. Könntet ihr für mich über den Code gucken und sagen, ob das alles so richtig ist?

Java:
public static void partnerSetup() {
        Map<Integer, ArrayList<Integer>> dbMap = new HashMap<Integer, ArrayList<Integer>>();
        String select = "SELECT ID, Jahre, Hat_Partner FROM individuen WHERE Familienstand IS 2 AND "
                + "Hat_Partner IS NULL AND Geschlecht IS 0 ORDER BY Jahre LIMIT 100;";
        Random r = new Random();
        int rnd;
      
        DBController dbc = DBController.getInstance();
        dbc.initDBConnection();
      
        try {
            Statement stmt = DBController.connection.createStatement();
            ResultSet rs = stmt.executeQuery(select);
          
            // Suche nach den richtigen Spaltennummern.
            int spalteID = rs.findColumn("ID");
            int spalteJahre = rs.findColumn("Jahre");
            while (rs.next()) {
                // Einlesen der jeweiligen Werte aus den Spalten
                int spalte1 = rs.getInt(spalteID);
                int spalte2 = rs.getInt(spalteJahre);
                ArrayList<Integer> dbList = new ArrayList<Integer>();
              
                // Schreiben der Spalten in die ArrayList
                dbList.add(spalte2);
                dbList.add(null); // Hier steht später die Altersspanne
                dbMap.put(spalte1, dbList);
            }
        }catch (SQLException e) {
            e.printStackTrace();
        }
      
        // Für jede, in die Hashmap kopierte Person die Altersspanne per Zufall aussuchen.
        for (Map.Entry<Integer, ArrayList<Integer>> entry : dbMap.entrySet()){
            int key = entry.getKey();
            ArrayList<Integer> tmpList = entry.getValue();
          
            rnd = r.nextInt(1000);
          
            if (rnd <= 960)
                tmpList.set(1, 10);
            else if (rnd >960 && rnd <= 995)
                tmpList.set(1, 15);
            else
                tmpList.set(1, 100);
            dbMap.put(key, tmpList);
        }
      
        ArrayList<Integer> spanne10 = new ArrayList<Integer>();
        ArrayList<Integer> spanne15 = new ArrayList<Integer>();
        ArrayList<Integer> spanneMax = new ArrayList<Integer>();
      
        for (int alter = 16; alter <= 100; alter++){
            for (Map.Entry<Integer, ArrayList<Integer>> entry : dbMap.entrySet()){
                int key = entry.getKey();
                ArrayList<Integer> tmpList = entry.getValue();
                if (tmpList.get(0) == alter && tmpList.get(1) == 10)
                    spanne10.add(key);
                else if (tmpList.get(0) == alter && tmpList.get(1) == 15)
                    spanne15.add(key);
                else
                    spanneMax.add(key);
              
            }
            if (!spanne10.isEmpty() || !spanne15.isEmpty() || !spanneMax.isEmpty()){
            partnerStmt(spanne10, alter, 1, 10);
            partnerStmt(spanne15, alter, 1, 10);
            partnerStmt(spanneMax, alter, 1, 10);
            }
            spanne10.clear();
            spanne15.clear();
            spanneMax.clear();
            System.out.println(alter);
        }
    }
 
Zuletzt bearbeitet von einem Moderator:
Du kannst dir auch ein Konstrukt in dieser Form basteln
Java:
HashMap<Integer, Person> map;

//...
public class Person {
    private int alter;
    private int altersspanne;
    // getter
}

Dein Code sieht sehr unsauber aus, dass heißt schwer zu lesen und viele magic number (über 24 Stück).
Wenn du versucht den Code clean zu halten, lösen sich auch die meisten Fragen.
 
Hallo Jardcore,

danke für den Hinweis. Ich denke wie viele Anfänger ist für mehr "sauberes coden" das schwerste am lernen. Dinge kompliziert umzusetzen ist seltsamerweise viel einfacher. 😉 Aber dafür bin ich ja hier.
Ich habe mich an deinen Tipp gehalten und das Ganze mit einem Objekt statt einer ArraList umgesetzt. Meiner Meinung nach ist es tatsächlich etwas übersichtlicher. Siehst du/ihr noch weitere Probleme oder Optimierungsmöglichkeiten?


Java:
public static void partnerSetup() {
        Map<Integer, PartnerSuche> dbMap = new HashMap<Integer, PartnerSuche>();
        String select = "SELECT ID, Jahre, Hat_Partner FROM individuen WHERE Familienstand IS 2 AND "
                + "Hat_Partner IS NULL AND Geschlecht IS 0 ORDER BY Jahre;";
        Random r = new Random();
        int rnd;
       
        DBController dbc = DBController.getInstance();
        dbc.initDBConnection();
       
        try {
            Statement stmt = DBController.connection.createStatement();
            ResultSet rs = stmt.executeQuery(select);
           
            // Suche nach den richtigen Spaltennummern.
            int spalteID = rs.findColumn("ID");
            int spalteJahre = rs.findColumn("Jahre");
           
           
            while (rs.next()) {
                // Einlesen der jeweiligen Werte aus den Spalten
                Familienstand f = new Familienstand();
                PartnerSuche person = f.new PartnerSuche();
                int spalte1 = rs.getInt(spalteID);
                person.setAlter(rs.getInt(spalteJahre));
               
               
                // Schreiben der Spalten in die HashMap
                dbMap.put(spalte1, person);
            }
        }catch (SQLException e) {
            e.printStackTrace();
        }
       
        // Für jede, in die Hashmap kopierte Person die Altersspanne per Zufall aussuchen.
        for (Entry<Integer, PartnerSuche> entry : dbMap.entrySet()){
            int key = entry.getKey();
            PartnerSuche person = entry.getValue();
           
            rnd = r.nextInt(1000);
           
            if (rnd <= 960)
                person.setAltersspanne(10);
            else if (rnd >960 && rnd <= 995)
                person.setAltersspanne(15);
            else
                person.setAltersspanne(100);
            dbMap.put(key, person);
        }
       
        ArrayList<Integer> spanne10 = new ArrayList<Integer>();
        ArrayList<Integer> spanne15 = new ArrayList<Integer>();
        ArrayList<Integer> spanneMax = new ArrayList<Integer>();
       
        for (int alter = 16; alter <= 100; alter++){
            for (Entry<Integer, PartnerSuche> entry : dbMap.entrySet()){
                int key = entry.getKey();
                PartnerSuche person = entry.getValue();
                if (person.getAlter() == alter && person.getAltersspanne() == 10)
                    spanne10.add(key);
                else if (person.getAlter() == alter && person.getAltersspanne() == 15)
                    spanne15.add(key);
                else if (person.getAlter() == alter)
                    spanneMax.add(key);
               
            }
            if (!spanne10.isEmpty() || !spanne15.isEmpty() || !spanneMax.isEmpty()){
            partnerStmt(spanne10, alter, 1, 10);
            partnerStmt(spanne15, alter, 1, 10);
            partnerStmt(spanneMax, alter, 1, 10);
            }
            spanne10.clear();
            spanne15.clear();
            spanneMax.clear();
            System.out.println(alter);
        }
    }
 
Könntest du nochmal erläutern was genau du vorhast, also ohne Code spezifisch zu werden?

Generell kannst du die erwähnten Magic Numbers durch Konstanten ersetzten.
Java:
private static final int MIN_ALTER = 16;
private static final int MAX_ALTER = 100;
// usw.

If Bedingungen selbst wenn es nur eine Zeile ist, am besten immer mit Klammern versehen, das gibt sonst nur Fehler. Manchmal vergisst mans und wollte doch eigentlich mehr als eine Zeile ausführen^^
 
Zuletzt bearbeitet von einem Moderator:
Könntest du nochmal erläutern was genau du vorhast, also ohne Code spezifisch zu werden?

Oke, ich versuche mich noch mal daran. ^^
Ich habe eine Hashmap, in der sich eine ID aus einer SQLite Datenbank und die dazugehörige Variablen Alter und eine am Anfang leere Variable Altersspanne befindet. Letztere werden jetzt durch ein Objekt "person" repräsentiert.
Die alter in der Hashmap variieren zwischen 16 und 100 Jahren. Da ich von der Altersspanne und dem Alter der Person abhängig in der Datenbank nach einem passenden Partner suchen will, würfel ich zunächst für jede Person die altersspanne zusammen. Dafür durchlaufen ich eben jeden Eintrag in meiner Hashmap. Konstante kann ich für die Spanne leider nicht benutzen, da es eben darum geht nachher in der Datenbank nach passenden Partnern zu suchen, abhängig von dem Alter und eben der Spanne.
Danach will ich die Hashmap durchlaufen und diese nach Alter und Spanne filtern. Die Idee dahinter ist, dass ich so Gruppierungen bekomme, die ich als Batch in meiner Tabelle updaten kann, um nicht zu viele Schreib- und Lesezugriffe zu haben wie wenn ich jede einzelne Person updaten würde.
 
Hashmap SQLite usw. sind schon wieder Code spezifisch^^

Heißt Altersspanne die Jahre, die vor und hinter dem Alter der Person liegen dürfen?
Also Peter ist 16Jahre alt und hat eine Altersspanne von 100, darf er dann mit anderen gematched werden die -84 bis 116 Jahre alt sind? Oder meinst du 100 +- 16... also 84 bis 116. Wie ist Altersspanne zu verstehen?^^
Code:
SELECT Id FROM Personen AS p
WHERE p.alter >= (altersspanne - alterDerAbzufragendenPerson) AND
p.alter <= (altersspanne + alterDerAbzufragendenPerson);

Wie du merkst ist es gar nicht so einfach Dinge zu erklären^^
Vielleicht ist es auch hilfreich gar nicht die Altersspanne zu nehmen, sondern für die PersonDaten ein min und ein max Alter zu bestimmen.
 
Heißt Altersspanne die Jahre, die vor und hinter dem Alter der Person liegen dürfen?

Es bedeutet tatsächlich, dass die Partner bei 16-jährigen -84 bis 116 sein dürfen. In der Methode, die die Tabelle updated wird das aber abgefangen und das Mindestalter zum matchen auf 18 gesetzt. Sonst würde ich ja Kinderheirat erlauben.

Wie du merkst ist es gar nicht so einfach Dinge zu erklären^^
Ich weiß, vor allem beim programmieren. Und erst recht wenn man sich nicht direkt sehen kann.

Vielleicht ist es auch hilfreich gar nicht die Altersspanne zu nehmen, sondern für die PersonDaten ein min und ein max Alter zu bestimmen.
Würde das den Code denn besser machen? Genau das mache ich dann ja in der nächsten Methode.
 
Naja in den bekannten Parterbörsen gibt man meines Wissens auch ein min und max Alter ein.
Dann kannst du in deiner Abfrage einfach alle Personen filtern, die zwischen min und max liegen.

Ich weiß nicht genau ob du deine Datenbank auch selbst befüllst, oder ob das eine vorgefertigte Lehrdatenbank oder sowas ist^^ Sonst ist es ja alles bei dir .)
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben