# Hierarchie mit HashMap darstellen



## Resthirn (15. Aug 2012)

Hallo,

irgendwie stehe ich auf dem Schlauch.

Und zwar will ich eine CSV-Datei einlesen und die Elemente als Hierarchie darstellen.

Die CSV hat z.b. folgenden Aufbau:


```
Bekleidung;Hose;kurz;gelb;
Bekleidung;Hose;kurz;rot;
Bekleidung;Hose;lang;blau;ohne Taschen;
Bekleidung;Hose;lang;blau;mit Taschen;
Bekleidung;Hose;lang;schwarz;ohne Taschen;
Bekleidung;Jacke;Jeans;schwarz;
```

Den Aufbau im Baum kann sich nun jeder vorstellen.

Wie kann ich das ganze nun in einer Hierarchie/Baumstruktur darstellen, ohne JTree nutzen zu müssen?

Also mit "darstellen" meine ich im Speicher und nicht auf dem Bildschirm. Die Hierarchie soll später in einer Datenbank mit Parent-IDs geschrieben werden;(

Danke für eure Anregungen.


----------



## Marco13 (16. Aug 2012)

Im Zweifelsfall mit einer eigenen "TreeNode"-Klasse, ziemlich straightforward. Warum HashMap? Wie soll darauf denn zugegriffen (oder wie soll damit rumgerechnet) werden?


----------



## Lumaraf (16. Aug 2012)

Ich würde statt einer HashMap eher auf eine TreeMap setzen. Aus der Reihenfolge der Einträge läßt sich dann auch ziemlich einfach eine Baumstruktur aufbauen.


----------



## maki (16. Aug 2012)

Wozu die Map?

Hierarchien kann man auch nur mit Listen darstellen.


----------



## SlaterB (16. Aug 2012)

eine Map ist für mich da auch die natürliche Wahl
"Bekleidung" zeigt auf Liste mit Strings "Hose", "Jacke",
"Hose" -> "lang", "Kurz"
usw.

eigene Klassen mit Nachfolgerlisten usw. sind sicherlich Alternative


----------



## Resthirn (18. Aug 2012)

SlaterB hat gesagt.:


> eine Map ist für mich da auch die natürliche Wahl
> "Bekleidung" zeigt auf Liste mit Strings "Hose", "Jacke",
> "Hose" -> "lang", "Kurz"
> usw.



ja genau. Nur leider scheine ich zu blöd zu sein, einen Schleifendurchlauf zu programmieren, um die HashMaps in der entsprechenden Hierarchie abzubilden damit das dann so aussiehht 


```
HashMap - Key "Bekleidung"
     |
     +--- Hashmap - Key "Hosen"
               |
               +--- HashMap - Key "kurz"
               |         |
               |         +--- HashMap - Key "gelb"
               |         +--- HashMap - Key "blau"
               |
               +--- HashMap - Key "lang"
                         |
                         +--- HashMap - Key "schwarz"
                         +--- HashMap - Key "blau"
```


----------



## faetzminator (18. Aug 2012)

Wenn du mit Maps arbeitest, hast du aber das Problem, dass du immer (mit [c]instanceof[/c] oder [c]getClass()[/c]) testen musst, ob denn der aktuelle Node ein Endknoten mit Daten, ein weiterer Knoten (Map) oder noch nichts (null) ist.
Wenn du dir eine eigene Datenstruktur schreibst, kannst du sogar noch so tolle Sachen wie [c]toString()[/c], [c]insert(String path)[/c] oder [c]T get(String path)[/c] anbieten


----------



## Resthirn (18. Aug 2012)

ja, okay. Aber mein größtes Problem ist überhaupt die Hierarchie abzubilden?!

Woher weiß ich denn im Schleifendurchlauf, dass z.B. "schwarz" ein Child von "lang", das wiederum ein Child von "Hose" und das wiederum ein Child von "Bekleidung" ist?


----------



## Spacerat (18. Aug 2012)

Maps? No...
Perhaps you might implement something like that:  (Tschuldigung... lerne grad' englisch XD)

```
public interface Node<T extends Node<T, V>, V> extends Set<T> {
  V getValue();
  V setValue(V value);
}
```


----------



## Mujahiddin (18. Aug 2012)

Spacerat hat gesagt.:


> Maps? No...
> Perhaps you might implement something like that:  (Tschuldigung... lerne grad' englisch XD)
> 
> ```
> ...



[OT]hahaha, du sollthest erst mal deutsch lernen, bevor du dich in andere Sprachen wagst! [/OT]


----------



## andreT (18. Aug 2012)

[OT]


Spacerat hat gesagt.:


> Maps? No...
> Perhaps you might implement something like that:  (Tschuldigung... lerne grad' englisch XD)
> 
> ```
> ...


Was soll mir eine Aussage wie _"Die Hierarchie soll später in einer Datenbank mit Parent-IDs geschrieben werden"_ genau sagen? Ich finde die Antwort passt schon ganz gut zur Frage/Problemstellung 
[/OT]

Aber jetzt mal ehrlich : Wie GENAU soll die Datenstruktur auf der DB denn nachher aussehen? Ist die vorgegeben oder nach deinem Ermessen? Was soll hier Parent-ID im o.g. Kontext (Parent-ID von was?) heißen?
Im Moment schaut mir die Objektstruktur erstmal ziemlich trivial aus und ich frage mich warum du da so einen Aufriss draus machen willst/sollst?! Was ist da dein Ziel bzw. wo soll "die Reise" hingehen ?


----------



## SlaterB (18. Aug 2012)

Resthirn hat gesagt.:


> ja, okay. Aber mein größtes Problem ist überhaupt die Hierarchie abzubilden?!
> 
> Woher weiß ich denn im Schleifendurchlauf, dass z.B. "schwarz" ein Child von "lang", das wiederum ein Child von "Hose" und das wiederum ein Child von "Bekleidung" ist?



beim Aufbau der Map/ sonstigen Datenstruktur weißt du es direkt aus den Rohdaten, aus einer Zeile
> Bekleidung;Hose;lang;schwarz
baust jede Verbindung einzeln auf,

was später bei der Auswertung der Map/ sonstigen Datenstruktur haben willst, musst du erstmal in Worte fassen,
allgemein hangelst du dich von Verknüpfung zu Verknüpfung


----------



## Resthirn (18. Aug 2012)

Also ich bekomme eine CSV in dem Aufbau oben mit rund 2000 Kategorien geliefert:


```
KATEGORIE_EBENE1;KATEGORIE_EBENE2;KATEGORIE_EBENE3;KATEGORIE_EBENE4;KATEGORIE_NAME1
KATEGORIE_EBENE1;KATEGORIE_EBENE2;KATEGORIE_EBENE3;KATEGORIE_EBENE4;KATEGORIE_NAME2
KATEGORIE_EBENE1;KATEGORIE_EBENE2;KATEGORIE_EBENE3;KATEGORIE_EBENE4;KATEGORIE_EBENE5;KATEGORIE_NAME1
```

Daraus brauche ich den Hierarchiebaum. Mit dem Hierarchiebaum kenne ich dann den Parent und kann einen neuen Datensatz in meine Tabelle Schreiben. Diese Tabelle hat folgenden Aufbau:


```
ID|NAME|PARENT_ID
```

Und nun?





SlaterB hat gesagt.:


> beim Aufbau der Map/ sonstigen Datenstruktur weißt du es direkt aus den Rohdaten, aus einer Zeile
> > Bekleidung;Hose;lang;schwarz
> baust jede Verbindung einzeln auf,
> 
> ...



ja aber die Verschachtelung ist dynamisch tief. mal 5 Ebenen, mal 2 oder mal 13. Und ich bekomme den Aufbau mit der dynamischen Tiefe nicht hin. Bei einer Starren Tiefe von z.B. 3 Ebenen wäre das kein Problem...


----------



## bERt0r (18. Aug 2012)

Wie wärs mit 

```
class Kategorie
{
HashMap<Kategorie> subKategorien;
String bezeichnung;

//get,set,Konstruktor
}
```


----------



## Resthirn (18. Aug 2012)

bERt0r hat gesagt.:


> Wie wärs mit
> 
> ```
> class Kategorie
> ...



ja klar. aber ich kriege das nicht gebacken das in der Schleife aufzubauen.

mit 


```
KATEGORIE_EBENE1;KATEGORIE_EBENE2;KATEGORIE_EBENE3;KATEGORIE_EBENE4;KATEGORIE_NAME1
KATEGORIE_EBENE1;KATEGORIE_EBENE2;KATEGORIE_EBENE3;KATEGORIE_EBENE4;KATEGORIE_NAME2
KATEGORIE_EBENE1;KATEGORIE_EBENE2;KATEGORIE_EBENE3;KATEGORIE_EBENE4;KATEGORIE_EBENE5;KATEGORIE_NAME1
```

hätte ich eine Schleife mit 3 Durchläufen, und in jedem Durchlauf hätte ich ein String-Array mit 5 bzw. 7 Inhalten.

Wie baue ich nun die Verschachtelung mit den Subkategorien dann auf?


----------



## bERt0r (18. Aug 2012)

Du kennst schon eine while schleife oder? Ansonsten kannst du es auch rekursiv machen.


----------



## andreT (18. Aug 2012)

Resthirn hat gesagt.:


> Also ich bekomme eine CSV in dem Aufbau oben mit rund 2000 Kategorien geliefert:
> 
> 
> ```
> ...



Du stellst dir doch wohl keinen Datensatz à la *ID|NAME|PARENT_ID* <-> *42|gelb|0815* vor wobei *0815* die ID von sowas wie *kurz* ist, oder? Wenn doch, würd ich nochmal gründlich über das Datenmodell nachdenken!



Resthirn hat gesagt.:


> ja aber die Verschachtelung ist dynamisch tief. mal 5 Ebenen, mal 2 oder mal 13. Und ich bekomme den Aufbau mit der dynamischen Tiefe nicht hin. Bei einer Starren Tiefe von z.B. 3 Ebenen wäre das kein Problem...



Beliebig tiefe Verschachtelungen sind eigtl. nicht das Problem wenn man mit Bäumen arbeitet. Die kann man sich (wie ja schon vorgeschlagen wurde) auch selbst basteln. Hier mal ein paar Lösungsansätze (siehe Links im Thread) : 
http://www.java-forum.org/java-basics-anfaenger-themen/134367-klasse-fuer-baumstrukturen.html
// Zwar ein Binärer Suchbaum, macht es aber ggf. noch klarer bzw. optimierter.
JAVA Tutorial Deutsch #60 - Binärer Suchbaum [GER] [HD] - YouTube


----------



## Resthirn (18. Aug 2012)

andreT hat gesagt.:


> Du stellst dir doch wohl keinen Datensatz à la *ID|NAME|PARENT_ID* <-> *42|gelb|0815* vor wobei *0815* die ID von sowas wie *kurz* ist, oder? Wenn doch, würd ich nochmal gründlich über das Datenmodell nachdenken!



wieso das denn? Mehr brauche ich nicht außer den Namen und die ID von dem Parent.

Wenn das alles so einfach ist, dann schreib mir doch bitte einer den Code wie ich die Hierarchie mit HashMaps aus den 3 oben genannten Zeilen bekomme damit das dann so aussieht:


```
HashMap - Key "Bekleidung"
     |
     +--- Hashmap - Key "Hosen"
               |
               +--- HashMap - Key "kurz"
               |         |
               |         +--- HashMap - Key "gelb"
               |         +--- HashMap - Key "blau"
               |
               +--- HashMap - Key "lang"
                         |
                         +--- HashMap - Key "schwarz"
                         +--- HashMap - Key "blau"
```

Mit dem JTree habe ich das ja fertig, bekomme es aber mit den HashMaps nicht hin...


----------



## andreT (18. Aug 2012)

Resthirn hat gesagt.:


> wieso das denn? Mehr brauche ich nicht außer den Namen und die ID von dem Parent.


Na dann ...



Resthirn hat gesagt.:


> Wenn das alles so einfach ist, dann schreib mir doch bitte einer den Code ...


Das hatte ich schon vermutet :roll:

Da sind doch super Beispiele in den Links zu finden. Und mit HashMaps, Schleifen ...


----------



## faetzminator (18. Aug 2012)

Ist doch in 5min geschrieben 

```
import java.util.LinkedHashMap;
import java.util.Map;

public class Node {

    private final Map<String, Node> children = new LinkedHashMap<String, Node>();

    private final String key;

    protected static final String NEW_LINE = System.getProperty("line.separator");

    public Node(String key) {
        this.key = key;
    }

    public String getKey() {
        return key;
    }

    public Map<String, Node> getChildren() {
        return children;
    }

    public Node getChild(String key) {
        return children.get(key);
    }

    public void addChild(Node child) {
        children.put(child.getKey(), child);
    }

    @Override
    public String toString() {
        return getStringBuilder(0).toString();
    }

    protected StringBuilder getStringBuilder(final int n) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; i++) {
            sb.append(' ');
        }
        sb.append("- " + getKey() + NEW_LINE);
        for (Node entry : getChildren().values()) {
            sb.append(entry.getStringBuilder(n + 2));
        }
        return sb;
    }
}
```


```
public static void main(String[] args) {
    final Node root = new Node("root");
    add(root, "KATEGORIE_EBENE1;KATEGORIE_EBENE2;KATEGORIE_EBENE3;KATEGORIE_EBENE4;KATEGORIE_NAME1");
    add(root, "KATEGORIE_EBENE1;KATEGORIE_EBENE2;KATEGORIE_EBENE3;KATEGORIE_EBENE4;KATEGORIE_NAME2");
    add(root,
            "KATEGORIE_EBENE1;KATEGORIE_EBENE2;KATEGORIE_EBENE3;KATEGORIE_EBENE4;KATEGORIE_EBENE5;KATEGORIE_NAME1");
    System.out.println(root);
}

public static void add(final Node root, String input) {
    Node current = root;
    for (String key : input.split(";")) {
        Node child = current.getChild(key);
        if (child == null) {
            current.addChild(child = new Node(key));
        }
        current = child;
    }
}
```
Was gibts aus?

```
- root
  - KATEGORIE_EBENE1
    - KATEGORIE_EBENE2
      - KATEGORIE_EBENE3
        - KATEGORIE_EBENE4
          - KATEGORIE_NAME1
          - KATEGORIE_NAME2
          - KATEGORIE_EBENE5
            - KATEGORIE_NAME1
```


----------

