Methode verallgemeinern (Methode als Parameter)?

Ion

Mitglied
Hallo,

ich bin grade dabei anhand einer XML Konfigurationsdatei Objekte zu erstellen und halt generell erst einmal ein wenig mti XML umgehen. Ich bin dabei auf ein mehr oder weniger kleines "Problem" gestoßen.

Ich habe mich hier (http://www.java-samples.com/showtutorial.php?tutorialid=152) erst einmal ein wenig zum Thema XML eingelesen und auch sonst in der Doku etc. nachgelesen.

Da gibt es ja diese Methode um das Dokument zu parsen (unter dem Punkt Using Dom Punkt b). Allerdings habe ich in meiner XML Datei schon einige unterschiedliche Tags und ich wollte dafür dann einen eigenen Teil erstellen, also ab if.

Also anstatt diesem Teil hier:
Java:
private void parseDocument(){
    //get the root element
    Element docEle = dom.getDocumentElement();

    //get a nodelist of elements
    NodeList nl = docEle.getElementsByTagName("Employee");
    if(nl != null && nl.getLength() > 0) {
        for(int i = 0 ; i < nl.getLength();i++) {

            //get the employee element
            Element el = (Element)nl.item(i);

            //get the Employee object
            Employee e = getEmployee(el);

            //add it to list
            myEmpls.add(e);
        }
    }
}

das:

Java:
private void parseDocument()
{ 
  //get the root element
  Element docEle = dom.getDocumentElement();

  //get a nodelist of elements
  NodeList nl1 = docEle.getElementsByTagName("Employee");
  NodeList nl2 = docEle.getElementsByTagName("Customer");
  NodeList nl3 = docEle.getElementsByTagName("Prdouct");
  // usw.
 
  getElement(nl1, Employee);
  getElement(nl2, Customer);
  // usw ..
}

und dann ebend eine Methode um die Elemente zu holen und zu erstellen.

Java:
private void getElement(NodeList nl, Object obj, ArrayList al) // Methode als Parameter?
{
    if(nl != null && nl.getLength() > 0)
    {
        for(int i = 0 ; i < nl.getLength();i++)
        {             
            //get the employee element
            Element el = (Element)nl.item(i);

            //get the Employee object
            obj = getEmployee(el); // oder ebend getCustomer oder wie auch immer

            //add it to list
            al.add(obj);
        }
    }
}

Aber bei dem Punkt
Java:
Employee e = getEmployee(el);

Müsste dann ja immer eine andere Methode stehen. Wie kann man das machen, das ich da je unterschiedliche Methoden aufrufe aber trotzdem die Methode allgemein halte? Es macht ja wenig Sinn, die Methode 10x oder mehr zu machen und dabei sind dann ja nur die NodeList, das Objekt, die Methode die aufgerufen werden soll und die ArrayList, zu der das Element dann hinzugefügt werden soll oder?

Die Methoden sähen dann ja auch so ähnlich aus, wie in dem Tutorial unter Punkt c)
Java:
private Employee getEmployee(Element empEl) {

    //for each <employee> element get text or int values of
    //name ,id, age and name
    String name = getTextValue(empEl,"Name");
    int id = getIntValue(empEl,"Id");
    int age = getIntValue(empEl,"Age");

    String type = empEl.getAttribute("type");

    //Create a new Employee with the value read from the xml nodes
    Employee e = new Employee(name,id,age,type);

    return e;
}

Nur das sich dann natürlich noch der Rückgabetyp zu ebend dem Objekt ändern würde. Mein Ansatz macht doch da durchaus Sinn oder nicht?

Ich habe jetzt nur ebend Probleme mit dieser Methode, die dann da aufgerufen werden soll. Kann man also irgendwie die Methode da als Parameter definieren, die dann bei
Java:
obj =
aufgerufen werden soll?
 

Flown

Administrator
Mitarbeiter
So ich weiß nicht wie fit du mit Java 8 bist, aber Lambda Expressions dürften dich jetzt am weitesten bringen:
Java:
private void parseDocument() {
  Element docEle = dom.getDocumentElement();
  
  NodeList nl1 = docEle.getElementsByTagName("Employee");
  NodeList nl2 = docEle.getElementsByTagName("Customer");
  NodeList nl3 = docEle.getElementsByTagName("Prdouct");
  
  List<Employee> employees = new ArrayList<>();
  List<Customer> customers = new ArrayList<>();
  List<Product> prodcuts = new ArrayList<>();
  
  getElement(nl1, employees, this::getEmployee);
  getElement(nl2, customers, this::getCustomer);
  getElement(nl3, prodcuts, this::getProduct)
}

private <T> void getElement(NodeList nodes, List<T> collector, Function<Element, T> func) {
  if (nodes != null) {
    for (int i = 0; i < nodes.getLength(); i++) {
      Element el = (Element) nodes.item(i);
      collector.add(func.apply(el));
    }
  }
}

Aber selbst ohne Lambda-Kenntnisse brauchst du ein Interface dass dir als Input ein Element und als Rückgabewert dein gewünschtes "geparstes" Element liefert. Soetwa wie Function<Element, T>
 

Ion

Mitglied
Naja, so soll es wohl ungefähr aussehen. Das mit den Kunden, Produkten etc. war ja wie oben schon gesagt nur als Beispiel gedacht.
So sieht die XML Datei wohl ungefähr aus, wobei ich jetzt nur bei den Räumen, Kreaturen etc. nur einen Auszug der Attribute habe. Ich bin mir auch nicht sicher, ob die Struktur der Datei so okay ist. Wäre schön, wenn du (oder jemand anderes) sich das mal anschauen könnte.

Code:
<?xml version="1.0"?>
<Karte>
    <Raum>
        <name></name>
        <beschreibung></beschreibung>
        <ausgaenge>
     
        </ausgaenge>
    </Raum>
    <Raum>
        <name></name>
        <beschreibung></beschreibung>
        <ausgaenge> 
        </ausgaenge>
    </Raum>
 
    <Kreatur>
        <name></name>
        <raum></raum>
    </Kreatur>
    <Kreatur>
        <name></name>
        <raum></raum>
    </Kreatur>
 
    <Gegenstand>
        <name></name>
        <beschreibung></beschreibung>
    </Gegenstand>
        <name></name>
        <beschreibung></beschreibung>
    </Gegenstand>
</Karte>

Dazu sei mal angemerkt, das auch durchaus mehrere Karten (Level) erzeugt werden können und natürlich x Räume, n Gegenstände und m Kreaturen usw. Es gibt auch noch Fähigkeiten, Effekte, spezielle Gegenstände usw.

Ich frage mich halt auch, ob bspw. die Monster eigentlich ein Unterattribut des jeweiligen Raumens sein sollten und die Gegenstände auch? Dann gäbe es ja aber auch bspw. noch die Fähigkeiten. Sollen die dann ein Unterattribut der Kreatur oder des Lebewesens (wie auch immer) sein oder ist das so wie oben schon okay?

Mit Java 8 bin ich um ehrlich zu sein leider noch nicht so bewandert. Irgendwie verstehe ich deinen Code auch oben nicht ganz und irgendwie fehlt ja der Teil, wo dann das Objekt geholt werden soll?

Zudem verstehe ich nicht, warum du nicht eine ArrayList direkt oben als Paramter in der Funktion gewählt hast, sondern stattdessen eine Liste? Klar, so geht das auch aber ist das nicht egal oder machst du das wegen des Typs?
Was die Zeile
Java:
collector.add(func.apply(el));

dann hier genau bewirken soll, ist mir auch nicht ganz klar. Soll dann die Funktion des Interfaces aufgerufen werden? Wie soll denn dann das Interface aussehen? Ich hatte mich ja online auch schon mal erkundet aber das große Problem wären dann ja eigentlich die Variablen oder nicht? Wie kriege ich Element und den Typen T mit in das Interface rein? Kann mir irgendwie nicht vorsellen, wie das dann funktionieren soll.
 

Flown

Administrator
Mitarbeiter
Also nicht verzweifeln. Ich muss jetzt meinen kleinen Jungen ins Bett bringen und liefere dir morgen dann eine große Erklärung. Eventuell könntest du dir derweil:
  • Generics
  • Lambda-Expressions
  • JAXB
ansehen.

Vielleicht wird dir dann einiges klarer.
 

Flown

Administrator
Mitarbeiter
Allgemein gesprochen: Heutzutage braucht man keine eigene Persistierung mehr schreiben, denn dafür gibt es schon zu mächtige Frameworks (wie JAXB, JPA, Hibernate, ...). Da du dich für eine XML Persistierung entschlossen hast, rate ich dir, setze dich mit JAXB auseinander. Du schreibst dir deine Klasse und annotierst die Attribute bzw. die Elemente deiner Klasse die du in deiner XML speichern willst. Dann übergibst du deine Klasse dem Framework und schon ist dein Objekt in einer XML gespeichert.

Ich hab dir eine kleine Beispiel-Klasse mit deinem Kontext gebastelt:
Java:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

public class XMLTest {

   public static final String XML_FILE_NAME = "./states.xml";

   public static void main(String...args) {
     List < Room > rooms = new ArrayList < > ();
     rooms.add(new Room("Room 1", "Starting room", 1));
     rooms.add(new Room("Room 2", "Finishing room", 0));

     Player p = new Player("Hero", 100, 100);

     MyGameStates states = new MyGameStates(rooms, p);
     System.out.println(states);

     try {
       MyGameStates.save(states, new FileOutputStream(XML_FILE_NAME));
     } catch (FileNotFoundException | JAXBException e) {
       System.err.println("Error during saving: " + e.getMessage());
       e.printStackTrace();

     }

     MyGameStates loaded = null;
     try {
       loaded = MyGameStates.load(new FileInputStream(XML_FILE_NAME));
     } catch (FileNotFoundException | JAXBException e) {
       System.err.println("Error during loading: " + e.getMessage());
       e.printStackTrace();
     }
     System.out.println(loaded);

   }

}

@XmlRootElement(name = "gamestates")@XmlAccessorType(XmlAccessType.NONE)
class MyGameStates {@XmlElementWrapper(name = "rooms")@XmlElement(name = "room")
   List < Room > rooms;@XmlElement(name = "player")
   Player p;

   public MyGameStates() {}

   public MyGameStates(List < Room > rooms, Player p) {
     this.rooms = rooms;
     this.p = p;
   }

   public List < Room > getRooms() {
     return rooms;
   }

   public void setRooms(List < Room > rooms) {
     this.rooms = rooms;
   }

   public Player getP() {
     return p;
   }

   public void setP(Player p) {
     this.p = p;
   }

   public static MyGameStates load(InputStream input) throws JAXBException {
     return (MyGameStates) JAXBContext.newInstance(MyGameStates.class).createUnmarshaller().unmarshal(input);
   }

   public static void save(MyGameStates states, OutputStream output) throws JAXBException {

     Marshaller marshaller = JAXBContext.newInstance(MyGameStates.class).createMarshaller();
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
     marshaller.marshal(states, output);
   }

   @Override
   public String toString() {
     return "MyGameStates [rooms=" + rooms + ", p=" + p + "]";
   }

}

@XmlRootElement(name = "room")@XmlAccessorType(XmlAccessType.NONE)
class Room {
   private String name;
   private String description;
   private int exits;

   public Room() {}

   public Room(String name, String description, int exits) {
     this.name = name;
     this.description = description;
     this.exits = exits;
   }

   @XmlElement(name = "name")
   public String getName() {
     return name;
   }

   public void setName(String name) {
     this.name = name;
   }

   @XmlElement(name = "description")
   public String getDescription() {
     return description;
   }

   public void setDescription(String description) {
     this.description = description;
   }

   @XmlElement(name = "exits")
   public int getExits() {
     return exits;
   }

   public void setExits(int exits) {
     this.exits = exits;
   }

   @Override
   public String toString() {
     return "Room [name=" + name + ", description=" + description + ", exits=" + exits + "]";
   }
}

@XmlRootElement(name = "player")@XmlAccessorType(XmlAccessType.NONE)
class Player {
   private String name;
   private int health;
   private int mana;

   public Player() {}

   public Player(String name, int health, int mana) {
     this.name = name;
     this.health = health;
     this.mana = mana;
   }

   @XmlElement(name = "name")
   public String getName() {
     return name;
   }

   public void setName(String name) {
     this.name = name;
   }

   @XmlElement(name = "health")
   public int getHealth() {
     return health;
   }

   public void setHealth(int health) {
     this.health = health;
   }

   @XmlElement(name = "mana")
   public int getMana() {
     return mana;
   }

   public void setMana(int mana) {
     this.mana = mana;
   }

   @Override
   public String toString() {
     return "Player [name=" + name + ", health=" + health + ", mana=" + mana + "]";
   }

Um das von gestern trotzdem noch zu wiederholen, warum das funktioniert:
Du hast ein Interface mit Generics, dass ein Element entgegen nimmt und dir dann dein gewünschtes anderes Element (Article, Customer, Employee) liefert.
In Java ist es üblich gegen Interfaces zu implementieren, d.h. bei ArrayList macht man üblicherweiße:
Java:
List<T> list = new ArrayList<>();
Das bedeutet, dass man die Implementierung maskiert und man sie einfach austauschen kann (z.B. gegen eine LinkedList)

Vor Java 8 hätte man ein Interface gemacht dass einen Typ S entgegen nimmt und ihn in ein Typ T verwandelt:
Java:
interface Converter<S, T> {
  T getFrom(S from);
}

Dann hat man leichtes Spiel bei der Anwendung mit anonymen Klassen, die die Konvertierung übernehmen:
Java:
  private void load() {
     NodeList nl1 = ...; // Employee
     NodeList nl2 = ...; // Customer
     NodeList nl3 = ...; // Article

     List < Employee > employees = getElements(nl1, new Converter < Element, Employee > () {

       @Override
       public Employee getFrom(Element from) {
         return getEmployee(from);
       }
     });

     List < Customer > customers = getElements(nl1, new Converter < Element, Customer > () {

       @Override
       public Customer getFrom(Element from) {
         return getCustomer(from);
       }
     });

     List < Article > articles = getElements(nl1, new Converter < Element, Article > () {

       @Override
       public Article getFrom(Element from) {
         return getArticle(from);
       }
     });

  }

  private < T > List < T > getElements(NodeList nl, Converter < Element, T > converter) {
     List < T > result = new ArrayList < > ();
     for (int i = 0; i < nl.getLength(); i++) {
       Element el = (Element) nl.item(i);
       result.add(converter.getFrom(el));
     }
     return result;
  }

Wenn du hilfe beim Verstehen brauchst, dann melde dich noch einmal.
 

Ion

Mitglied
Naja, verzweifeln tu ich noch nicht. Da bin ich auch doch schon ein wenig abgehärtet aber das hat auch andere Gründe aber das gehört hier nicht hin.

Übrigens erwarte ich hier keine Antwort (oder Hilfe) nach nur am besten einer Stunde oder ähnlichem. Ich kann auch durchaus ein paar Tage warten.

---------------------------------------------------------------------

XML ist doch heute ein durchaus gängiges Format oder nicht? Irgendwie finde ich, dass das auch für sowas gut passt oder nicht?

Eigentlich brauche ich auch das speichern gar nicht, weil ich eigentlich nur die Karte von der XML aus aufbauen wollte. Dementsprechend brauche ich den Spieler eigentlich auch nicht, also zumindest in der XML Datei nicht. Der wird dann beim Start selbst vom Anwender erstellt.

Danke übrigens für das kleine (etwas größere) Beispiel, eigentlich wär das gar nicht so detailliert nötig gewesen aber naja, sei's drum. Danke. ;)

Ich hätte da tatsächlich noch ein paar Fragen zum Vorgehen bzw. zum Verständnis.
1. Da ich ja, wie oben gesagt keine Speicherfunktion brauche, muss ich das mit
Java:
@XmlRootElement(name = "room")@XmlAccessorType(XmlAccessType.NONE)
über dem Raum z.B ja eigentlich gar nicht mit einbauen, richtig?

2. Warum erstellst du eigentlich im Programm zwei Räume und übergibst die Liste dann? Sollte man das dann nicht lieber wirklich schon alles in der MyGameStates Klasse (bei dir) machen?

3. Das bei dem XML... name = "..", entspricht das da genau dem Namen, der auch inder XML Datei steht oder wird da Groß- und Kleinschreibung ignoriert?

4. Was würde denn dann eigentlich passieren, wenn in der XML Datei z.B keine Räume etc. gefunden werden oder wenn es da einfach nur das Oberelement gamestates (bei dir) geben würde? Wie könnte man sowas eigentlich auch dann überprüfen, falls da nichts geladen wurde?

5. Vom Vorgehen her wäre mir das jetzt auch ehrlich gesagt nicht ganz klar, wo dann jetzt die Objekte (Räume, Kraturen, Gegesntände etc.) dann wirklich erstellt werden sollen?

Ich würde die Klasse MyGameStates eigentlich eh eher umbennen, da diese ja dann wirklich nur die XML Datei lädt. Da wäre ja z.B sowas wie Loader oder XMLLoader oder so passender.

Sollten die Objekte dann in der Klasse auch erstellt werden? Eigentlich brauche ich die Methode setRooms ja warscheinlich auch nicht, höchstens die getRooms Methode, falls man diese dann zurückgibt aber das müsste man dann ja für alle Objekte machen?

6. Ehrlich gesagt bin ich jetzt ein wenig verwirrt ..
Das was ich dann ja in meinem erstem post hier geschrieben habe brauche ich dann ja nicht mehr, richtig? Also nur noch das, was du geschrieben hast? (im Prinzip).

Das, was du mir unter deinem Beispiel geschrieben hast, war dann nur noch einmal zur Aufklärung?

Den Rest von deinem kleinem (großen) Beispiel verstehe ich wohl aber das mit dem Interface weiter unten irgendwie nicht ganz. Wenn man dann einfach
Java:
interface Converter<S, T> {
  T getFrom(S from);
}

schreibt, dann müssten T und S doch beide Typen sein oder nicht? So würde das doch bestimmt nicht kompilieren?
 
Zuletzt bearbeitet:

Ion

Mitglied
Noch einmal zwei Sachen:
1. Hat es eigentlich einen Grund, warum du für die load Methode das Ergebnis in einer Variable speicherst oder ist das jetzt nur zu Testzwecken?

2. Wenn ich das jetzt mal so umsetze, erst einmal nur für den Raum kriege ich direkt einen Fehler:
Code:
Raum enthält keinen "no-arg"-Standardkonstruktor.
    this problem is related to the following location:
        at Raum
        at private java.util.List MapLoader.raueme
        at MapLoader

Brauch dann jede Klasse auch einen Standardkonstruktor oder liegt das an was anderem? Ich habe jetzt mal erst einmal zwei Testräume erstellt aber ich kriege nur die zwei (Eingang und Ausgang), wie bei dir in dem Beispiel ausgegeben.

Java:
@XmlRootElement(name = "map")@XmlAccessorType(XmlAccessType.NONE)
public class MapLoader
{
    @XmlElementWrapper(name = "raueme")@XmlElement(name = "raum")
    private List <Raum> raueme;

    public MapLoader()
    {
     
    }
 
    public MapLoader(List <Raum> raueme)
    {
        this.raueme = raueme;
     
        for(Raum raum : raueme)
            System.out.println(raum.getKurzeBeschreibung());
    }

    public List <Raum> getRooms()
    {
        for(Raum raum : raueme)
            System.out.println(raum.getKurzeBeschreibung());
 
        return raueme;
    }

    public void setRooms(List <Raum> raueme)
    {
        this.raueme = raueme;
    }

    public static MapLoader load(InputStream input) throws JAXBException
    {
        return (MapLoader) JAXBContext.newInstance(MapLoader.class).createUnmarshaller().unmarshal(input);
    }

    @Override
    public String toString()
    {  
        return "MapLoader [rooms=" + raueme + "]";
    }
}

Wobei die loaded Methode, wie bei dir im Beispiel auch zwei Raüme (bei mir) ausgibt aber nur das Objekt aber der Raum wurde ja auch noch nicht instanziert.
 
Zuletzt bearbeitet:

Flown

Administrator
Mitarbeiter
XML ist ein gängiges Format, da liegst du richtig.

Zu deinen Fragen:

1. Du brauchst beim Laden genau die Informationen, wie das Objekt aufgebaut ist, um das Mapping durchzuführen (aber einfach mal ausprobieren).
2. Das ist ein Testprogramm, um dir zu zeigen wie das gehen könnte, damit du etwas experimentieren kannst und ich habs jetzt als Testzwecke so gemacht.
3. Google doch mal ob XML case sensitive ist?!
4. Mein Tipp an dich: Einfach ausprobieren. Aber du könntest ja die Anzahl der Räume als Attribut speichern, die Räume in eine Liste laden und überprüfen, ob die Anzahl und die Listengröße ident sind.
5. Das kommt drauf an wie du was in deinem Programm benötigst. Du brauchst manche Methoden, damit JAXB die richtigen Objekte erstellt. Sie dir doch mal das JAXB Tutorials im Netz an, da gibt es zig davon und es beantwortet dir die meisten deiner Fragen (ich betreibe hier kein Tutorium, sondern biete jediglich Antworten zu konkreten Fragen - alles andere sollst und musst du dir selbst erarbeiten. Alles was darüber hinausgeht, sieh es als Goodwill meinerseits an)
6. Du kannst es auf deine Art genau so mache, aber wenn du fixe Objekte in deinem Programm hast und diese serialisieren möchtest (in XML), dann nimm doch ein Framework, dass dir die Arbeit abnimmt. Wenn du weißt wie deine XML aufgebaut ist und du nur gewisse Sachen für den Aufbau deines Programms benötigst, dann ist der DOM-Weg auch gut - mehrere Wege führen nach Rom, der Rest ist geschmackssache.


Jetzt nochmal zu den Interfaces: Ich habe dir gesagt, du sollst dir Generics anschauen, dass beantwortet deine Fragen. Generics sind Typen zur Laufzeit und S, T sind Typen (eben dynamische, die bei der Laufzeit bekannt sind).

Zu deinem letzten Posting:
1. Ich hab es einfach so gemacht, um einen Weg aufzuzeigen, mehrere Wege fü.......
2. Du brauchst keinen Default-Konstruktor, du kannst auch Adapter nehmen (ebenfalls Googlen: "JAXB without default constructor"). Sonst ja.
 

Ion

Mitglied
Ahja, also erstellt jaxb die Objekte auch direkt? Scheint ja so zu sein, das habe ich auch grade herausgefunden. XML scheint auch case-sensitiv zu sein. ;)

Zu 4)
Naja, scheint jeweils sehr krasse Fehlermeldung zu werfen.

Zu 5)
Aber jaxb erstellt die Objekte dann doch auch direkt oder kann man das auch unterbinden? Wann müsste man das denn "manuell" regeln?

Zu dem zweiten Posting:
2) Da scheint mir der Weg über den Standardkonstruktor einfacher zu sein ...
Irgendwie verstehe ich aber nicht, warum jaxb überhaupt einen braucht? Weil die Objekte automatisch von jabx erzeugt werden oder wie? Normal wird doch der Standardkonstruktor sowieos auch immer von dem Compiler erzeugt oder nicht?

Ich habe jetzt auch mal ein wenig experimentiert und anscheinend brauche ich dann ja über die getter auch keine XmlElement zu schreiben aber ich musste jetzt auch setter für jaxb erstellen, die dann ja automatisch aufgerufen werden. Dabei bin ich aber auf ein Problem gestoßen:
Bei dem Raum habe ich eine setter Methode, die einen Raum als Nachbar definiert aber die Methode erwartet zwei Paramter, einmal eine enum (eine Richtung) und der Raum, der der Nachbar ist. Dann müsste ich in der XML ja warscheinlich sowas haben oder?
Code:
<?xml version="1.0"?>
<map>
    <raueme>
        <raum>
            <beschreibung>Raum 1</beschreibung>
            <ausgaenge>
                <ausgang>
                    <richtung>norden</richtung>
                    <nachbar>raum2</nachbar>
                </ausgang>
            </ausgaenge>
        </raum>
        <raum>
            <beschreibung>Raum 2</beschreibung>
        </raum>
    </raueme>
</map>

Nur wie weise ich das dann nachher der setter Methode zu?
Java:
public void setNachbar(Richtung richtung, Raum nachbar)
{
  // setze Ausgang ...
}

Bei der Beschreibung ist es ja leicht ..
Java:
 @XmlElement(name = "beschreibung")
public void setBeschreibung(String beschreibung)
{
    this.beschreibung = beschreibung;
}

aber wie weise ich dann sozusagen auch auf den nächsten Raum? Dafür brauche ich doch dann eine Referenz oder nicht? Ich habe ja (glaube ich) weiter oben geschrieben, das es ja auch Kreaturen etc. gibt. Diese befinden sich dann ja auch in den Räumen. Da bräuchte ich doch dann ja auch eine Referenz?
Würdest du das denn sozusagen so aufbauen:
Code:
<?xml version="1.0"?>
<map>
    <raueme>
        <raum>
            <beschreibung>Raum 1</beschreibung>
            <ausgaenge>
                <ausgang>
                    <richtung>norden</richtung>
                    <nachbar>raum2</nachbar>
                </ausgang>
            </ausgaenge>
        </raum>
        <raum>
            <beschreibung>Raum 2</beschreibung>
        </raum>
    </raueme>
    <kreaturen>
        <kreatur>
            <name>Schlange</name>
            <raum>raum2</raum>
        </kreatur>
    </kreaturen>
</map>

oder würdest du das in den Raum integrieren, also so:
Code:
?xml version="1.0"?>
<map>
    <raueme>
        <raum>
            <beschreibung>Raum 1</beschreibung>
            <ausgaenge>
                <ausgang>
                    <richtung>norden</richtung>
                    <nachbar>raum2</nachbar>
                </ausgang>
            </ausgaenge>
            <kreatur>
                <name>Schlange</name>
                <raum>this?</raum>
            </kreatur>
        </raum>
        <raum>
            <beschreibung>Raum 2</beschreibung>
        </raum>
    </raueme>
</map>

obwohl es ja ein eigenes Objekt ist aber da wäre dann ja auch die Frage:
Wie kann ich dann im Programm sagen, das der Raum in der XML Datei, wo sich auch die <Kreatur> drin befindet, in dem <Raum> ist?
 

Flown

Administrator
Mitarbeiter
Natürlich erstellt JAXB dir deine Elemenete, darum musst du auch die Klassen für die Objekte annotieren, damit er die richtigen setter findet! Den Default-Konstruktor benötigt er, weil er dein Objekt via setter füllt, außer eben du implementierst es mit Adapter (aber das sagt ich auch schon).

Zu deinem 5.: Manuell müsste man es mit Adapter machen (wieder im Netz suchen)

Natürlich ist es über den Standardkonstruktor einfacher Objekte zu erstellen. Man darf nicht vergessen, dass das alles über Reflections instanziert wird.
Der Default-Konstruktor wird nur erzeugt, falls es keinen anderen Konstruktor gibt (Grundlagenwissen!).

Daten Kapseln ist das Stichwort für dein Problem mit zwei Attributen und du hast auch schon die Lösung! Erstell dir einfach eine Klasse Ausgang mit Referenz auf Raum und Richtung!


Also um eine clean XML zu besitzen, solltest du über Objektreferenzen nachdenken! Wie so häufig, bemüh doch Google dir zu helfen.

Nochmal: es führen mehrere Wege nach Rom und du versuchst Designentscheidungen auf mich/uns abzuwälzen. Mach dir einen Plan, hab davon eine Vorstellung und implementiere dann erst. Dann komm gerne mit konkreten Fragen zu uns.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Mittels Generics eine Methode verallgemeinern Allgemeine Java-Themen 2
W Hilfe bei Methode Allgemeine Java-Themen 14
Ü Methoden Arrays vergleichen - Methode Allgemeine Java-Themen 1
Simon16 compareTo Methode überschreiben Allgemeine Java-Themen 4
TheSkyRider Methode über DataInputStream "auslösen" Allgemeine Java-Themen 6
M CrudRepository save Methode mocken Allgemeine Java-Themen 6
thor_norsk toString() - Methode Allgemeine Java-Themen 6
A Clean Code: Variable vs. Methode Allgemeine Java-Themen 8
Encera Zweite Main-Methode zuschalten Allgemeine Java-Themen 18
M Optimierung einer Methode (byte-Geraffel) Allgemeine Java-Themen 2
I Hibernate Envers - Aufruf der Methode zum Speichern selbst ausführen oder managen? Allgemeine Java-Themen 0
N rekursion mehrfach eine Methode Öffnen Allgemeine Java-Themen 4
berserkerdq2 Wenn ich eine Methode nur jede 50ms ausführen will, wie mach ich das? Allgemeine Java-Themen 4
berserkerdq2 run-methode eines Threads so programmieren, dass 30x die Sekunde etwas ausgeführt wird. Allgemeine Java-Themen 44
N Schnellste Methode, ein Array durchzugehen? Allgemeine Java-Themen 9
E Methoden abstract static Methode Allgemeine Java-Themen 8
E Eine Methode einer extendeten Klasse deakitivieren Allgemeine Java-Themen 12
F Getter Methode aufrufen funktioniert nicht Allgemeine Java-Themen 1
B In Java Methode mit generic input und output basteln? Allgemeine Java-Themen 4
goldmensch Datentypen Welche Methode hat die bessere Performance? Allgemeine Java-Themen 12
R Lambda Expression in einer Methode execute() aufrufen (execute() ist eine Methode aus dem funktionalen Interface Command) Allgemeine Java-Themen 5
T C++ Methode Übersetzung in Java Allgemeine Java-Themen 3
L Erste Schritte TDD testen einer Methode mit injezierten Services? Allgemeine Java-Themen 12
R @author vor Methode (eclipse) Allgemeine Java-Themen 1
J RotSchwarzBaum: Löschen mittels insert-Methode Allgemeine Java-Themen 20
Y Java Bruttoberechnen + runden Methode Allgemeine Java-Themen 1
R Warum ist die Methode unendlich oft rekursiv? Allgemeine Java-Themen 5
R Methoden Was fehlt mir bzw. muss ich bei der Methode countHarshabNumbers ändern damit ich die Harshad Zahlen im Intervall [51, 79] zählen kann? Allgemeine Java-Themen 19
D ArrayListe delete Methode klappt nicht Allgemeine Java-Themen 12
Drachenbauer Wie finde ich den Aufrufer zu einer Methode, die sich nicht in meinem Projekt befindet? Allgemeine Java-Themen 2
A Ist ein enum hier richtig? Enum toString() Methode. Allgemeine Java-Themen 1
Scream_ilias brute force methode verbessern? Allgemeine Java-Themen 6
Scream_ilias passwort meines pc per brute force methode knacken Allgemeine Java-Themen 4
S static methode im Interface Allgemeine Java-Themen 1
M Konstruktor einer Methode Allgemeine Java-Themen 35
A HashMap Methode "get()"-Problem Allgemeine Java-Themen 28
E Hat der Compiler einen Fehler oder warumbeendet return nicht eine Methode ? Allgemeine Java-Themen 7
T Sinn einer toString Methode Allgemeine Java-Themen 3
T Split() Methode funktioniert nicht?! Allgemeine Java-Themen 11
L Methoden Über Reflections eine Methode mit aufrufen Allgemeine Java-Themen 3
S Kann ich eine Methode schreiben die alle Arten von funktionalen Interfaces akzeptiert..? Allgemeine Java-Themen 21
L ToString-Methode Allgemeine Java-Themen 6
X Datentypen NPE in längerer Methode Allgemeine Java-Themen 12
I Methoden Generics-Methode Allgemeine Java-Themen 3
H Strategy Pattern - changeColor() Methode - input rgd oder hex einlesen Allgemeine Java-Themen 1
T statische Variable und nicht-statische Methode Allgemeine Java-Themen 2
B Aufruf der Methode ergibt eine Exception Allgemeine Java-Themen 13
M Wie kann ich ein int[] Array in einer Methode benutzen? Allgemeine Java-Themen 6
M Wie kann man eine void Methode mit Variablen von zwei verschiedenen Objekten ausführen? Allgemeine Java-Themen 15
F Was ist der Dateityp meines Parameters für die Main Methode. Allgemeine Java-Themen 6
F Variablen Palindromzahl (Probleme mit Methode) Allgemeine Java-Themen 9
B APi methode kurz anhalten Allgemeine Java-Themen 8
P Methode aus anderem Paket aufrufen Allgemeine Java-Themen 1
K ursprüngliche ArrayList ändert sich bei Übergabe in Methode Allgemeine Java-Themen 18
R Rekursive Methode Allgemeine Java-Themen 8
ReinerCoder Methode einer Klasse meldet Fehler "misplaced construct(s)" Allgemeine Java-Themen 13
R Wo ist mein Fehler in der Methode DRINGEND Allgemeine Java-Themen 9
I Collection - contains-Methode überschreiben (anonyme innere Klasse) Allgemeine Java-Themen 4
E RMI NULL-Pointer-Exeception wenn der RMI-Proxy eine Methode deligiert Allgemeine Java-Themen 2
S Methoden Liste soll Methode aus innerer Klasse aufrufen Allgemeine Java-Themen 4
M Methoden Generische Methode für ArrayList Allgemeine Java-Themen 7
D HTTP Aufruf einer Methode aus einem Servlet heraus Allgemeine Java-Themen 0
C Threads Methode verhält sich merkwürdig Allgemeine Java-Themen 18
R rekursive und iterative Methode Allgemeine Java-Themen 3
P Methoden Anwendung der allMatch()-Methode Allgemeine Java-Themen 5
G Programm, das nach abgearbeiteter main Methode weiterläuft Allgemeine Java-Themen 72
D Methoden Methode zum Steinschnitt Allgemeine Java-Themen 2
U OOP Warum kann ich aus meiner Methode keinen String auslesen Allgemeine Java-Themen 4
T Methoden Methode zum durchsuchen einer ArrayList Allgemeine Java-Themen 8
D Returnwert aus einer Methode gerundet ausgeben lassen Allgemeine Java-Themen 2
S equals-Methode bestimmer Klassen abfangen Allgemeine Java-Themen 2
H Methoden Methode 'updateItem' der Klasse 'TreeCell' Allgemeine Java-Themen 3
snipesss Methode greift nicht auf JTextPanel zu Allgemeine Java-Themen 3
R Methode in Methode voraussetzen Allgemeine Java-Themen 8
S Überschriebene Methode der Oberklasse der Oberklasse aufrufen. Allgemeine Java-Themen 5
D Methode dynamisch aufrufen Allgemeine Java-Themen 2
Sogomn Methode als Parameter? Allgemeine Java-Themen 3
M Eigene forEach()-Methode funktioniert nicht. Allgemeine Java-Themen 2
KaffeeFan Methoden Suche Methode um Programm kurz warten zu lassen Allgemeine Java-Themen 22
G Methoden Aus einem Event, wo ich weiß, dass es ausgeführt werden wird, eine Get-Methode basteln Allgemeine Java-Themen 8
BRoll Methode abbrechen (Invoke von außen) Allgemeine Java-Themen 5
D generische Interface und konkrete Methode Allgemeine Java-Themen 3
G Threads Methode nebenbei ausführen, Status verarbeiten Allgemeine Java-Themen 4
H FTP Befehl/Java Methode für Submit im z/Os (Host) Allgemeine Java-Themen 1
M Fabrik Methode, gutes Beispiel? Allgemeine Java-Themen 0
M WebService - Zugriff auf Webservice Methode über Browser Allgemeine Java-Themen 1
N WaitForScript- methode in javafx Allgemeine Java-Themen 1
2 jede Stunde Methode ausführen Allgemeine Java-Themen 8
M Eine static-Methode verlassen Allgemeine Java-Themen 2
P "Overriden statische Methode" Statische Methode die vererbt wird Allgemeine Java-Themen 5
X Komponente an Methode übergeben Allgemeine Java-Themen 1
A Methode ergibt Java NullpointerException. Allgemeine Java-Themen 3
S Getestete Methode um das Beste aus URL-Nutzereingaben rauszuholen..? Allgemeine Java-Themen 4
L Methoden Methode gibt mir beim verschlüsseln mit RSA 0 bytes aus ? Allgemeine Java-Themen 1
D Methode mit optionalen Parametern in Interface Allgemeine Java-Themen 3
C DBConnection als Methode in mehreren Klassen Allgemeine Java-Themen 4
S Methode funktioniert nicht als ActionListener Allgemeine Java-Themen 4
M Methoden Methode Auslagern Allgemeine Java-Themen 6
P 4 Threads in einer Methode Allgemeine Java-Themen 2
A Methoden Generische Methode mit Arrays - Source Compatibility 1.7 benötigt, wieso? Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben