Übersicht trotz mehrdimensionaler Arraylisten

usrr

Bekanntes Mitglied
Hallo,

ich benutze eine mehrdimensionale ArrayList für eine Baumstruktur.

Beispiel:

Stadt->Haus->Zimmer

Jetzt fällt mir aber auf, dass der Programmcode unübersichtlich wird und ich zum Teil über einen erst ein paar Tage alten Code grübeln muss. Was fehlt ist der Bezug Stadt->Haus->Zimmer im Quelltext. Gibt es eine Technik die mir helfen könnte?

Java:
ArrayList<ArrayList<ArrayList<Zimmer>>> welt = new ...

Zimmer = welt.get(a).get(b).get(c);

Weiß jemand was ich meine?
 
Du sprichst schon selbst von einer Baumstruktur. Warum nutzt Du dann nicht einen Baum?

Alternativ halte die Daten in einer Datenbank und baue nicht den kompletten Baum auf, wenn Du ihn nicht brauchst.
 
sinnvoll wären auch richtige Klassen,
Klasse Stadt mit einer Liste von Häusern,
Klasse Haus mit einer Liste von Zimmern..

alle Daten eines Programmes passen in x GB linearen Arbeitsspeicher, aber erst mit Klassen und Objekten wirds schön damit zu arbeiten..
 
Sprechende Variablennamen verwenden:
Java:
Zimmer zimmer = welt.get(stadtNr).get(hausNr).get(zimmerNr);
liest sich doch schon leichter.
 
Danke für die Antworten.

Ich muss mich noch durchwühlen bis ich zum nächsten Plateau komme. Ich werde mal schauen ob ich den Code dann so umbauen kann, dass ein Baum verwendet wird.

Aber ich dachte eigentlich die ArrayList wäre schon ein Baum. Beim Googlen habe ich auch nur JTree gefunden. Gibt es da noch bessere Klassen für?
 
Du sprichst schon selbst von einer Baumstruktur. Warum nutzt Du dann nicht einen Baum?

Bei vorliegendem Konstrukt der Tiefe 3, wobei jede Ebene eine fest definierte andere Bedeutung hat, würde ich keinen Baum nehmen sondern ebenfalls Listen. Durch einen Baum zu iterieren und dann die Bedeutung des Knotens (Zimmer, Stadt, Haus) über die Tiefe herauszufinden, ist völlig intransparent.
Zudem müsste man entweder die Knoten untypisiert lassen oder sich selber eine aufwändige Baumdatenstruktur schreiben.

Java:
ArrayList<ArrayList<ArrayList<Zimmer>>> welt = new ...
Das Beispiel ist übrigens kein Baum sondern ein Wald, da kein Wurzelknoten existiert.
 
Zuletzt bearbeitet:
Ich glaube die Realisierung mit verschachtelten Collections ist schon in Ordnung, JTree ist ganz was anderes.
Edit: naja der Wurzelknoten wäre um übertragenen Sinne "welt", eben die oberste Collection.
 
Aber ich dachte eigentlich die ArrayList wäre schon ein Baum. Beim Googlen habe ich auch nur JTree gefunden. Gibt es da noch bessere Klassen für?

Naja, ein Tree ist IMHO eigentlich nur so etwas:

Java:
public class Tree {

    private Node rootNode;

    public Tree(...) {
        // init
    }

    public Node getRootNode() {
        return rootNode;
    }
}
Java:
public class Node {

    private List<Node> childs = new ArrayList<Node>();
    // und noch die privaten Felder...

    //...
}
 
Könnten diejenigen, die eigene Klassen vorschlagen, mal anskizzieren, wie die aussehen sollten? Naja... vielleicht nicht so wichtig... es ist eigentlich klar.
Der Pragmatische Programmierer auf meiner linken Schulter hat gesagt.:
Durch die Namen und definierten Typen bleibt der Code leichter verständlich und man kann leicht zusätzliche Methoden einbauen, die spezifisch für die jeweiligen Klassen sind :toll:
Der abstraktions-Geek auf meiner rechten Schulter hat gesagt.:
Eine Klasse zu erstellen, die genau die Semantik einer List hat ist doch voll sinnlos :autsch: und [c]List<List<List<Zimmer>>> welt;[/c] ist doch schon schön kurz.
🙁
 
List bietet ja um einiges mehr als notwendig, das liegt einfach daran, dass List eben eine generische Schnittstelle (nicht im Sinne von Java Generics) ist die für alle möglichen Anwendungen anwendbar sein sein.

Es heisst ja:
Je generischer eine Schnittstelle/API/Framework, umso schwieriger ist es sie zu nutzen, aber umso leichter ist sie wiederzuverwenden.
Bei konkreten Schnittstellen die ein spezifisches Problem behandeln, ist es einfach sie zu verwenden, aber sie sind schwieriger wiederzuverwenden.

Für dein beispiel:
Java:
List<List<List<Zimmer>>> welt ...
der meiste Code darin bezieht sich auf flexibilität die in diesem konkreten fall nie benötigt wird, einfacher wäre
Java:
Welt welt ...
Genauso verhält es sich mit den Methoden im List Interface, behaupte mal das von den 20+ Methoden mind. 80% nicht benötigt werden -> ziemlich schlechtes Singal/Rausch verhältnis, schwierirger zu verstehen als ein Welt Interface/Klasse mit vielleciht 4-6 spez. Methoden.
 
Naja, ein Tree ist IMHO eigentlich nur so etwas:

Bäume sind ein mathematisches Konstrukt; keine konkrete Implementierung. Ein Baum kann auch über eine statische Schachtelung von z.B. List erreicht werden. Die Tiefe ist dann vorgegeben. Wie du deinen Baum realisierst ist völlig egal. So lange er der Definition eines Baums genügt, ist es einer. 😉

Baum (Graphentheorie) ? Wikipedia
 
und da fällt mir auch was ein:
genau wie man List statt ArrayList nutzen sollte
(schließlicht heißt es im ersten Post gar ArrayList<ArrayList<ArrayList<Zimmer>>> welt),
könnte es hier eine eigene noch abstraktete Klasse sein,
für den Fall dass man später lieber intern auf Map oder wer weiß was wechselt

aber so gesehen könnte man ja jede Verwendung von List in allem Programmen streichen,
wann es sich lohnt muss man abschätzen, die Welt ist es vielleicht wert, der Wald wäre nicht genug™
 
Bäume sind ein mathematisches Konstrukt; keine konkrete Implementierung. Ein Baum kann auch über eine statische Schachtelung von z.B. List erreicht werden. Die Tiefe ist dann vorgegeben. Wie du deinen Baum realisierst ist völlig egal. So lange er der Definition eines Baums genügt, ist es einer. 😉

Baum (Graphentheorie) ? Wikipedia

Es kommt aber immer darauf an, ob die Nodes, welche keine "Blätter" sind (sondern "Zweige"), auch Daten halten müssen. Dann braucht man irgendwas wie ich es postete. Wenn man es mit einem [c]List<List<List<Foo>>>[/c] lösen kann, dann würde ich das einfach ein multidimensionales Array nennen.
 
Für Bäume gibt es doch auch ein Entwurfsmuster: Composite Pattern

Man kann mit diesem Entwurfsmuster Baumstrukturen abbilden. Es gibt aber - und das war mein Einwand an faetzminator - weitere Möglichkeiten.
Man kann z.B. auch Struktur und Inhalt eines Baumes in einem einzigen String codieren.

Sonst könnte man in Sprachen wie Assembler keine Bäume abbilden.
Es wäre sogar in Java für einen Benutzer einer KLasse gar nicht ersichtlich, ob diese intern den Baum in Knoten und Listen oder in einem einzigen String speichert.

@faetzminator
Das bei einer einfachen Schachtelung von Listen keine Inhalte bei den Knoten die keine Blätter sind, ist richtig. Da bin ich bei dir.
 
Zuletzt bearbeitet:
Hi langhaar, klar gibt es Alternativen, zB. kann man einen ganzen Baum in ein einziges Array packen 😉
Ein String mit einer sog. "Kaskadennummer" pro Knoten repräsentiert dann die Struktur

1
1.1
1.2
1.2.1
1.2.1.1
1.2.1.2
1.2.1.3

usw.

Kann etwas müsehlig sein den Baum zu traversieren 😉
Wenn die knoten aber schon in "pre order" reihenfolge im Array liegen, ist das traversieren sehr einfach.
Aufwendig ist dann nur noch das ein- und aushängen von Knoten.
 
Zuletzt bearbeitet von einem Moderator:
List bietet ja um einiges mehr als notwendig, das liegt einfach daran, dass List eben eine generische Schnittstelle (nicht im Sinne von Java Generics) ist die für alle möglichen Anwendungen anwendbar sein sein.

OK, dann würde mich jetzt DOCH mal so eine Klasse "Haus" interessieren... Sowas wie
Java:
class Haus
{
    private List<Room> rooms;
    public int getNumRooms() {
        return rooms.size();
    }
    public Room getRoom(int i) { 
        return rooms.get(i);
    }
}
wäre dann eine Option (mit Vor- und Nachteilen) und
Java:
class Haus
{
    private List<Room> rooms;
    public List<Room> getRooms() { 
        return Collections.unmodifiableList(rooms); 
    }
}
eine andere. Ich finde es halt praktisch, wenn man sowas machen kann wie
Java:
void collectAllRooms()
{
    List<Room> result = new ArrayList<Room>();
    for (Haus haus : hauser) {
        result.addAll(hasu.getRooms());
    }
}
Allgemein: Wenn man die gesamte Collections-Maschinerie verwenden kann, ohne per Hand irgendwelcher Schleifen basteln zu müssen wie
Java:
for (int i=0; i<haus.getNumRooms(); i++) ...

Aber spätestens wenn eine Klasse "Haus" nur eine Methode hat, die eine Liste von Rooms liefert, kann man dessen Existenzberechtigung in Frage stellen (abgesehen von den schon angedeuteten Dingen, dass irgendwann noch eine Methode "getHausnummer" oder so dazukommen kann... das muss man sich halt überlegen). Sonst könnte man auch auch gleich das machen, was IMHO extrem häßlich ist:
Java:
class Haus extends ArrayList<Room> { /* leer!!! */ }
...
 

Neue Themen


Zurück
Oben