# Sortieren von Objekten innerhalb eines Arrays



## Greenkobolt (14. Dez 2019)

Nabend Leute,

ich soll für die Uni die folgende Aufgabe lösen: 





> *Wunschliste*
> *Aufgabenstellung*
> In dieser Aufgabe müssen Sie neben einer Klasse _TestWunsch_ zwei weitere Klassen _Wunsch_ und _Wunschliste_ erstellen. Die Klasse _Wunschliste_ soll hierbei mehrere Wünsche aufsteigend sortiert nach ihrer Priorität mittels eines Feldes vom Typ _Wunsch_ verwalten.
> *Klasse Wunsch*
> ...



Hier direkt erstmal mein momentaner Code: 

```
public class Wunsch {
     String beschreibung;
     int prioritaet;
}

public class Wunschliste {
    Wunsch wuensche[];
}

public class TestWunsch {
    public static void main(String[] args) {
        Wunschliste b = erzeugeLeereWunschliste(4);
        Wunsch xy = neuerWunsch(b, "Auto", 2);
//        Wunsch xx = neuerWunsch(b, "Hallo", 3);
//        Wunsch xxx = neuerWunsch(b, "Dker", 4);
//        Wunsch xxa = neuerWunsch(b, "P2", 5);
//        Wunsch xax = neuerWunsch(b, "Dhasdf", 1);
        
        
    }
    public static int count = 0;
    public static Wunschliste erzeugeLeereWunschliste (int a) {
        Wunschliste wishList = new Wunschliste();
        wishList.wuensche = new Wunsch[a];
        return wishList;
}
    public static Wunsch neuerWunsch(Wunschliste b, String describe, int prio) {
        Wunsch wish = new Wunsch();
        wish.beschreibung = describe;
        wish.prioritaet = prio;
        if (wish.prioritaet < 0) {
            wish.prioritaet = 0;
        }
        if(count < b.wuensche.length) {
            
            if(b.wuensche[count] != wish) {
                b.wuensche[count] = wish;
                count++;
                
            }
        }
        return wish;
    }
//    public static String gibWuenscheaus(Wunschliste b){
//        String x = "";
//        for(int i = 0; i < b.wuensche.length -count+1; i++) {
//            x += (b.wuensche[i].beschreibung + " " + b.wuensche[i].prioritaet + "\n"); FEHLERHAFT.
//       
//            }
//        return x;
//    }
    

}
```

Ich habe also die geforderten Klassen Wunsch und Wunschliste erstellt (nach meinem Glauben ist das auch richtig so) und es soweit hinbekommen, dass die Methode "neuerWunsch" dazu führt, dass das Array nicht komplett gefüllt wird, sondern nach der count Variable jeweils nur der Platz.

Das eigentliche Problem:

Das Sortieren nach der Priorität. Ich habe bereits über Comparable oder Comparator gelesen und das ganze auch probiert. Auch mit dem @Override. Sollte ich das richtige gemacht haben, bekomme ich allerdings trotzdem dann jedes mal eine NullPointerException, wenn ich Arrays.sort(b.wuensche); ausführe.

Meine Vermutung ist, dass ich das Array falsch fülle? Wenn ich das, was ich gelesen habe, richtig verstanden habe, kommt es dann zur NullPointerException, wenn das Array "null" ist.

Vielen lieben Dank schonmal


----------



## Greenkobolt (14. Dez 2019)

Habs gelöst, hatte wohl einen Fehler beim Comparable.


----------



## Kirby.exe (17. Dez 2019)

Kann man das Problem mit dem Sortieren auch anders lösen? Also ohne ein if?


```
if(w.wuensche[w.wuensche.length-1] != null) { // <--------- Den Müll hier
                Arrays.sort(w.wuensche);
                boolean result = Arrays.stream(w.wuensche).anyMatch(wish::equals);
                //System.out.println("result: " + result);
                if(result) {
                    break;
                }else if(w.wuensche[i].getPriority() < wish.getPriority()) {
                    w.wuensche[i] = wish;
                    Arrays.sort(w.wuensche);
                    break;
                }
```

das Problem dabei ist halt in meinen Augen, dass wenn das Array wünsche eine Größe von 5 hat, dann ist das if erst nach dem 6. Eintrag erfüllt  Jedoch soll nach jedem Eintrag sortiert werden, wenn man jedoch das löscht dann gibt es eine wunderbare NullPointerException. Ich gehe mal davon aus, dass diese wegen dem Sort von einem nicht Kompleten Array kommt. Meine Frage wäre halt: Wie umgehe ich den Kram? Ich hatte zwar gelesen dass so etwas mit Tree Set oder Hash Maps einfacher geht, was wahrscheinlich auch richtig ist, jedoch müssen wir es mit einem Array vom Typ Wunsch machen(Wunsch [] wünsche).


----------



## Kirby.exe (17. Dez 2019)

Könnte man hiermit den NullPointer umgehen ?

```
Arrays.sort(Object[] a, int fromIndex, int toIndex)
```
Wenn man einfach bei jedem einlesen einen Counter nimmt und nur bis zu diesem Index sortiert?


----------



## Kirby.exe (17. Dez 2019)

Ok Selbstgespräche sind was schönes xD Das hat es tatsächlich gelöst


----------



## kneitzel (17. Dez 2019)

Du gibst uns ja keine Zeit zum antworten. Ja, das ist eine valide Lösung die Du da gefunden hast. 

Evtl. nur mal als kleiner Ausblick (womit ich aber dann wohl etwas vorgreife):
- In produktivem Code gehört das Verhalten eines Objektes mit zum Objekt. Also so Klassen bekommen nicht nur die Daten selbst sondern auch die Methoden. Und ein wichtiger Punkt ist dann die Kapselung. Also wie bei einer Waschmaschine: Du nutzt die Bedienungselement. Du wirst nicht auf die Idee kommen, da direkt zu sagen: meineWaschmaschine.Motor.setDrehzahl(xxxx). An dem Beispiel wird auch deutlich, wo die Probleme sind: denn um Beispiele zu nennen: Du musst wissen, wie die Übersetzung ist. Wie viele Umdrehungen beim Motor sorgen für eine Umdrehung der Trommel? Das kenne ich zumindest von meiner Waschmaschine nicht. Und wenn du das wissen solltest: Dann tauscht jemand die Waschmaschine aus und die hat evtl. eine andere Übersetzung ... Also nicht unproblematisch. Daher: Wir nutzen nur, was die Klasse wirklich nach außen bietet und nutzen keine "Innereien".
- Und später wird man bei Dingen, deren Anzahl flexibel ist, in der Regel kein Array mehr verwenden. Statt dessen würde man dann Klassen verwenden, die für eine dynamische Menge an Elementen gedacht sind. In Deinem Beispiel bietet sich z.B. direkt eine ArrayList an und deine Wunschliste könnte ein einfaches

```
public class Wunschliste extends ArrayList<Wunsch> {}
```
(Das ist nur ein Beispiel. Hier muss man genau überlegen, was überhaupt Sinn macht... Da gibt es viele Möglichkeiten und Ideen. Inheritance wie im Beispiel oder Composition - da hätte eine Wunschliste innen eine Instanzvariable vom Typ ArrayList<Wunsch> - nur um da eine Fragestellung / Option anzusprechen.)

Aber da ich da bestimmt einfach nur vorgegriffen habe: Wenn es verwirrend ist, dann vergiss es gleich wieder und warte bis es dran kommt. Aber wenn Du Spaß an der Sache hast und da mehr Zeit investieren willst, dann ist das evtl. auch schon ein interessanter Ansatz, dem Du auch etwas nachgehen könntest.


----------



## Kirby.exe (17. Dez 2019)

Ich muss noch die andere Übungsaufgabe lösen und dann setze ich mal dran und probiere ein wenig herum  Ich hatte gelesen dass es damit wesentlich einfacher oder zumindest effizienter funktioniert


----------



## mihe7 (17. Dez 2019)

Kirby_Sike hat gesagt.:


> Kann man das Problem mit dem Sortieren auch anders lösen? Also ohne ein if?


Klar, Du brauchst nur einen Zähler (Instanzvariable) für die Größe. Außerdem lassen sich die Daten effizient verwalten, wenn das Array als Heap organisiert wird.


----------



## Kirby.exe (17. Dez 2019)

mihe7 hat gesagt.:


> Klar, Du brauchst nur einen Zähler (Instanzvariable) für die Größe. Außerdem lassen sich die Daten effizient verwalten, wenn das Array als Heap organisiert wird.


Ja gut ich habe zwar schon von den Begriffen Stack und Heap gehört, aber ehrlich gesagt keinen Schimmer was du meinst xD

Meine Instanzvariable war einfach der Counter


----------



## mihe7 (17. Dez 2019)

Kirby_Sike hat gesagt.:


> Ja gut ich habe zwar schon von den Begriffen Stack und Heap gehört, aber ehrlich gesagt keinen Schimmer was du meinst xD


Jetzt kommt der ausgerechnet mit Stack und Heap daher... Mit Stack und Heap werden sowohl Datenstrukturen als auch Bereiche des Hauptspeichers verstanden. Ich meinte hier die Datenstruktur (hier ein min-heap)

Beim Einfügen wird das neue Element erstmal ans Ende gestellt. Sagen wir mal, das wäre Index i. Anschließend wird mit dem Eltern-Element an Position (i-1)/2 verglichen: hat das eingefügte Element eine niedrigere Prio, werden die Elemente vertauscht. Das wird so lange wiederholt, bis kein Tausch mehr notwendig bzw. möglich ist (weil das Element schon am Anfang des Arrays steht).

Das kleinste Element steht immer an der Wurzel. Um dieses zu entfernen, wird es durch das letzte Element ersetzt, anschließend wird das Element nach unten durchgereicht, indem es mit den Kindknoten (Index 2*i+1 bzw. 2*i+2) verglichen wird. Ist es größer, wird es mit dem kleineren Kindknoten vertauscht. Wiederholung, bis kein Tausch mehr notwendig ist.


----------



## Kirby.exe (18. Dez 2019)

Ich gehe mal stark davon aus dass wir dies am Ende des Semesters machen werden oder nächstes Semester in Komplexe Algorithmen und Datenstrukturen xD Ich kenn Heap nämlich wie gesagt nur aus dem Hauptspeicher xD


----------



## mihe7 (18. Dez 2019)

Kirby_Sike hat gesagt.:


> nächstes Semester in Komplexe Algorithmen und Datenstrukturen


Da würde es reinpassen.


----------



## Kirby.exe (18. Dez 2019)

xD @mihe7 du hast nicht reinzufällig Ahnung von Assembler? xD


----------



## mihe7 (18. Dez 2019)

Kirby_Sike hat gesagt.:


> xD @mihe7 du hast nicht reinzufällig Ahnung von Assembler? xD


Kommt darauf an. Worum geht es denn?


----------



## kneitzel (18. Dez 2019)

mihe7 hat gesagt.:


> Kommt darauf an. Worum geht es denn?


Bestimmt um https://www.java-forum.org/thema/zahlen-test-gerade-oder-ungerade-in-assembler.186757/


----------



## Kirby.exe (18. Dez 2019)

Yap xD


----------



## mihe7 (18. Dez 2019)

Ah, habs gesehen, mom.


----------

