sunny: Verkettete Listen "dynamisch" verschachteln

Beitrag lesen

Hallo!

das mit der Numerierung war also fürs Testen zwar noch irgendwie möglich, führt aber natürlich nicht zu einer Lösung. Wie kann ich so etwas "richtig" machen? Sodass die Objekte sozusagen "dynamisch" erstellt werden?

Da jedes bereits vorhandene BagWithPresents in deiner BagList hängt, mußt du dich Element für Element durch diese Liste hangeln, um bei jedem BagWithPresents vorbeizukommen, wenn du dort Geschenke reinpacken möchtest o. ä. Bei einfach verketteten Listen ist das auch gar nicht anders möglich.

Ja, genau das versuche ich seit einiger Zeit auch ...

Wenn dein Best-Fit-Algorithmus nach einem weiteren Sack für Geschenke verlangt, erzeugst du dir ein neues Objekt BagWithPresents und hängst es in die Liste – an welcher Stelle du das machst (Anfang, Ende, irgendwo mittendrin), ist deine Entscheidung. Die Referenz auf dieses neue Objekt brauchst du nicht extra außerhalb deiner Liste in einer Variablen zu speichern, da du das ja bereits in deiner BagList tust.

In diesem Fall natürlich nicht. Aber in dem Fall dass das Present in einen bereits vorhandenen Bag eingefügt werden soll, der ja irgendwo in der Liste liegen kann.

Dafür wollte ich eine Methode "bauen", die mir später immer die Referenz auf den passenden Bag liefern soll.

Diese Methode sieht bei mir im Moment (für Testzwecke) einfach so aus:

  
public Bag getBestBag(int actWeight, int capacityOfBags) {  
  
 Bag actBag = begin;  
  
 if (actBag == null) {  
  Bag newBag = new Bag(capacityOfBags);  
  return newBag;  
 }  
  
 while (actBag != null) {  
  
  if (actBag.getActWeight() <= 30) {  
   return actBag;  
  }  
  actBag = actBag.next;  
 }  
  
 Bag newBag = new Bag(capacityOfBags);  
 return newBag;  
}  

Zum Testen hab ich einfach mal gesagt, solang der aktuelle Bag noch weniger als 30 wiegt, gib einfach den aktuellen zurück, wenn nicht dann erstelle einen neuen. Ich weiß das ist gerade ein wenig gemurkst, aber ist momentan ja nur Herumgeteste.

Aufgerufen wird das Ganze hier (auch Testcode):

  
 BagList bags = new BagList();  
  
 for (int i = 0; i < weightOfPresent.length; i++) {  
  
  System.out.println("\n" + (i+1) + ". DURCHLAUF");  
  
  Bag bestBag = bags.getBestBag(weightOfPresent[i],capacityOfBags);  
  
  if (bestBag.getActWeight() == 0) {  
   bags.add(bestBag);  
  }  
  
  bestBag.add(new Present(weightOfPresent[i]));  
  System.out.println("Bag " + bestBag + " wiegt jetzt " + bestBag.getActWeight());  
 }  
 bags.print();  

Sprich, wenn der zurückgegebene Bag ein Gewicht von 0 hat (also ein neu erstellter ist), dann soll dieser der BagList hinzugefügt werden.
Und da hab ich jetzt wieder "Pfusch". Die Methode, die das hinzufügen ermöglicht:

  
 public void add(Bag obj) {  
  
  Bag newBag = new Bag(obj);  
  
  if (begin == null && end == null) {  
   begin = newBag;  
  }  
  else if (begin != null && end == null) {  
   begin.next = newBag;  
   end = begin.next;  
  }  
  else {  
   end.next = newBag;  
   end = end.next;  
  }  
 }  

Da wird zwar die Objektreferenz übergeben, aber dann ja für die Liste ein neues Objekt erzeugt, deswegen funktioniert das Ganze nicht, das erste Element beim ersten Aufruf ist nicht dasselbe ... Deswegen wollte ich das Ganze nun so abändern, dass hier kein neues Objekt erzeugt wird, sondern als begin direkt das übergebene Objekt gesetzt wird.

Aber dann funktioniert meine Print-Methode nicht mehr:

  
 public void print() {  
  
  Bag actBag = begin;  
  int i = 1;  
  
  while (actBag != null) {  
      System.out.println("Bag " + i + " with " + actBag.element.getActWeight() + " gramm. (" + actBag + ")");  
      actBag = actBag.next;  
      i++;  
     }  
 }  

... weil hier dann eine NullPointerException auftritt, auch wenn auf actBag.next != null geprüft wird ... schön langsam bin ich nur mehr verwirrt, kann mir irgendjemand aus diesem Wirrwar heraushelfen? Wie löst man denn sowas, das ist doch eigentlich alles ganz einfach!? Ohweh ...

Lg,
sunny