# Sortierte Listen - Methode suchen



## Wave (31. Okt 2012)

Hallo,
mit Hilfe einer einfach verketteten Liste mit Kompositum ist die Methode "suchen" implementiert mit der Annahme: Es wird nach Objekten anhand eines Suchkriteriums gesucht, das genau einmal vorkommen kann (quasi Primärschlüsselwert).
Jetzt muss die Methode so abgeändert werden, dass nach einem Wert gesucht werden kann, der aber mehrmals in der Liste bei den Objekten vorkommen soll (bei mir: "Preis").


Bisher sieht die Methode so aus (für das Suchen nach einem Wert, der genau einmal vorkommen kann):

```
public Bett eintragSuchen(double suchdatum){        // Preis
        if(bettliste.datenknotenGeben(new Bett(suchdatum, 0, "", 0, 0, 0)) == null){
            System.out.println("Fehler!");
            return null;
        }
        else{
            return ((Bett) bettliste.datenknotenGeben(new Bett(suchdatum, 0, "", 0, 0, 0)).inhaltGeben());   
        }     
}
```

Ich hab versucht, mit while das umzuschreiben, aber wenn mehrere Objekte zutreffen gibts Probleme mit dem return. Kann mir einer helfen, was ich abändern muss?
Danke.

Zur Info:


```
public abstract class Listenelement{
    
    public abstract Listenelement naechsterGeben();
    public abstract Datenelement inhaltGeben();
    public abstract Datenknoten datenknotenGeben(Datenelement suchinhalt);
    public abstract Listenelement sortiertEntfernen(Datenelement suchinhalt);
    public abstract Listenelement sortiertEinfuegen(Datenelement de);
    public abstract Datenknoten hintenEinfuegen(Datenelement de);
    public abstract Datenelement inhaltLetzterGeben(Datenelement aktuellerInhalt);
    public abstract int anzahlDatenknotenGeben();
    public abstract void listendatenAusgeben();
    
}

public class Datenknoten extends Listenelement{

    private Listenelement naechster;
    private Datenelement inhalt;
    
    public Datenknoten(Listenelement le, Datenelement de){
        naechster = le;
        inhalt = de;
    }
    
    public void naechsterSetzen(Listenelement le){
        naechster = le;
    }
    
    public Listenelement naechsterGeben(){
        return naechster;
    }
    
    public Datenelement inhaltGeben(){
        return inhalt;
    }    
    
    public Datenknoten datenknotenGeben(Datenelement suchinhalt){
        if(inhalt.istGleich(suchinhalt)){
            return this;
        }
        else{
            return naechster.datenknotenGeben(suchinhalt);
        }
    }
    ...
}

public class Abschluss extends Listenelement{
  
    public Listenelement naechsterGeben(){
        return this;
    }
  
    public Datenelement inhaltGeben(){
        return null;
    }
    
    public Datenknoten datenknotenGeben(Datenelement suchinhalt){
        return null;
    }
   ...   
}

import java.util.*;
public class Bett extends Datenelement{

    private double preis;
    private int artnr;
    private String bezeichnung;
    private Calendar imSortimentSeit = new GregorianCalendar();
    
    public Bett(double pr, int anr, String bez, int jahr, int monat, int tag){
        preis = pr;
        artnr = anr;
        bezeichnung = bez;
        imSortimentSeit.set(jahr, monat, tag);
    }
    ...

}
```


----------



## SlaterB (1. Nov 2012)

beim bisherigen eintragSuchen() kann man stark bemängeln, dass du unnötig doppelten Code hast,
schreibe lieber

```
Bett b = (Bett) bettliste.datenknotenGeben(new Bett(suchdatum, 0, "", 0, 0, 0));
        if(b == null){
            System.out.println("Fehler!");
            return null;
        }
        return b.inhaltGeben();
```
die erste Zeile lieber auch noch aufspalten, eine Variable 'Bett suche = ..'
bloß nicht zuviel in einer Zeile zusammenfassen, gerade als Anfänger

------

was deine Methode jetzt mit mehreren machen soll ist aber unklar,
man kann nichts programmieren bevor nicht die Aufgabe klar ist, was soll passieren?
in einer Schleife mehrere suchen, soso, und was dann nun zurückgeben? alle in einer Liste oder das letzte Element oder oder?

die Methode eintragSuchen() ist dabei ja auch nicht primär bzw. allein beteiligt, es geht auch um die Liste,
willst du die rekursive Methode datenknotenGeben() ändern, dass diese mehrere zurückgeben kann,
oder soll eintragSuchen() sich nicht mehr allein auf datenknotenGeben() verlassen, sondern selber die Liste Element für Element durchlaufen?

all das sind sicher auch deine Fragen, aber du kannst nicht einfach um Code bitten 
um die 5 Zeilen geht es letztlich gar nicht (nur), sondern primär um die Fragen, die ich formuliert habe,
nachdenken und sinnvoll über das Programm, die Datenstrukturen, die Vorgänge Aussagen treffen


----------



## TryToHelp (1. Nov 2012)

Wie SlaterB sagt, musst du nun anstelle eines einzelnen Wertes eine Liste zurück geben. Da du ja nach mehreren Suchst, kann das ja nicht mit einem einzelnen Objekt funktionieren.

Also von so


```
public Datenknoten datenknotenGeben(Datenelement suchinhalt){
...
}
```

in so


```
public List<Datenknoten> datenknotenGeben(Datenelement suchinhalt){
...
}
```

Du kannst es entweder weiterhin rekursiv lassen, wie du es zur Zeit hast, oder itterativ, beide Wege führen zum Ziel ;-)


----------



## Wave (1. Nov 2012)

Wenn ich 

```
import java.util.*;

public class Verwaltung{

    private Sortierteliste bettliste;       // Sortierung nach dem Preis
    
    public Verwaltung(){
        bettliste = new Sortierteliste();
    }

   ...
    
        public List<Bett> eintragSuchen(double suchdatum){        // Suche nach dem Preis
        Datenknoten suchdatenknoten = bettliste.datenknotenGeben(new Bett(suchdatum, 0, "", 0, 0, 0));
        if(suchdatenknoten == null){
            System.out.println("Fehler!");
            return null;
        }
        else{
            return (Bett) suchdatenknoten.inhaltGeben();   
        }     
    }
   ...
}
```

gibt es Probleme mit return (incompatible types). Hier benötige ich Hilfe.

Zum Problem:  In der Liste suchen (nach dem Preis als Suchkriterium), aber jetzt kann es sein, dass der gleiche Preis in mehreren Datenelementen der Liste vorkommt. Somit gibt es nicht mehr höchstens einen Treffer, sondern evtl. mehrere. Man soll nun alle Treffer ausgeben.

Das mit dem Tipp "List <...> " würde ich gerne aufnehmen, aber "List" haben wir noch nicht gelernt. Daher bitte ich hier eben um Unterstützung. 


Wenn ich die Methode 

```
public Datenknoten datenknotenGeben(Datenelement suchinhalt){
        return erster.datenknotenGeben(suchinhalt);
    }
```

in 

```
public List <Datenknoten> datenknotenGeben(Datenelement suchinhalt){
        return erster.datenknotenGeben(suchinhalt);
    }
```
umschreibe, gibts auch Fehlermeldung bei return. 
Muss ich dann in den Klassen LISTENELEMENT, ABSCHLUSS, DATENKNOTEN auch den Typ der Methode auf List<Datenknoten> ändern?

Danke für einen Tipp!


----------



## TryToHelp (1. Nov 2012)

Ok, wenn Ihr List also eine Liste noch nicht hattet, wird es schwerer.
Ja also der Datentyp muss umgewandelt werden. momentan hast du nur ein Einzelnes Objekt, aber du willst ja mehrere Objekte. Da du nur ein Objekt zurück geben kannst, brauchst du ein konstrukt, was mehrere Objekte beinhalten kann. Dieses ist zum Beispiel eine Liste kann aber auch ein Array sein, falls ihr das schon hattet, finde ich aber für sowas nicht so toll, da man Listen viel einfacher erweitern kann.
List


----------



## Wave (1. Nov 2012)

Danke!!!

Jetzt habe ich:


```
public ArrayList<Bett> eintragSuchen3(double suchdatum){        // Alternativ, Suche nach dem Preis
        ArrayList<Bett> ergebnis = new ArrayList<Bett>();
        Datenknoten suchdatenknoten = bettliste.datenknotenGeben(new Bett(suchdatum, 0, "", 0, 0, 0));
        if(suchdatenknoten == null){
            System.out.println("Fehler!");
            return null;
        }
        else{
            return (Bett) suchdatenknoten.inhaltGeben();   
        }     
    }
```


Da gibts Probleme mit dem return. Wie muss ich dann das return umschreiben?
Was muss ich ändern, wenn statt ArrayList ---> List geschrieben werden muss, wie auch vorher vorgehschlagen wurde?


----------



## SlaterB (1. Nov 2012)

das ganze Posting von 10:52 ist strenggenommen nur eine Wiederholung der bisherigen Fragen + an manchen Stellen Einbau des Wortes List

nur wenn du 
> public List <Datenknoten> datenknotenGeben
statt
> public Datenknoten datenknotenGeben

schreibst, ändert sich doch nicht die Methode, gibt auf einmal mehrere Elemente zurück?
du musst denken und arbeiten, sicherlich das schwerste was man hier im Forum vermitteln kann..

fällt dir irgendwas in menschlicher Sprache zur Methode

```
public Datenknoten datenknotenGeben(Datenelement suchinhalt){
        if(inhalt.istGleich(suchinhalt)){
            return this;
        }
        else{
            return naechster.datenknotenGeben(suchinhalt);
        }
    }
```
ein? kannst du als ersten Schritt schon beschreiben, was sie bisher macht?
und was sie anders machen müsste, irgendwelche Ideen, Probleme zu beschreiben?

----------

> Das mit dem Tipp "List <...> " würde ich gerne aufnehmen, aber "List" haben wir noch nicht gelernt. Daher bitte ich hier eben um Unterstützung. 

da du gerade die Suche in einer LISTE programmierst, ist das etwas unfreiwillig komisch,
du könnste deine eigene List-Klasse verwenden, um mehrere Elemente zu sammeln,

setzt natürlich voraus, das du weißt was eine Liste ist, was du da gerade machst, worin du suchst,
kannst du einfach nur 5 Elemente in einer Liste speichern?
solches Grundverständis des Programms, mit dem du arbeitest, einer LISTE!!, wäre hilfreich

------

> Was muss ich ändern, wenn statt ArrayList ---> List geschrieben werden muss, wie auch vorher vorgehschlagen wurde? 

z.B.
> List<Bett> ergebnis = new ArrayList<Bett>();
statt
> ArrayList<Bett> ergebnis = new ArrayList<Bett>();

Rückgabetyp ändern usw., für den Anfang ist ArrayList aber auch gut genug,
der Rest der Methode macht bisher aber leider noch nicht viel dazu, in Liste einfügen usw.


----------



## Wave (1. Nov 2012)

Lieber SlaterB,

bei allem Respekt:
du warst auch Anfänger! Ich tue mich schwer, wenn wir die Liste (mit Kompositum aufgezogen) gerade lernen und hier nun ein DANKBARER Tipp mit fertigen "List" kommt, was bei mir (noch) nicht behandelt wurde.
Gerne kannst du "LIVE" und nicht hinter einem Computer versteckt in unsere Klasse kommen, wer weiß, ob du auch so feuerig mit Worten um dich wirfst.
Ich habe höflich um Hilfe gebeten. Wenn du einem "nichtdenkenden" Menschen nicht helfen willst, dann denke es dir persönlich, aber tue es nicht hier im Forum auf diese Art kund.
Das hat auch mit "Netiquette" zu tun. 
Nochmals: Jeder fängt von klein an! Erinnere dich selbst an diese Zeiten, wo man um jede Hilfe dankbar ist und wenn sie noch so albern/ billig/ ungeschickt anmuten mag.
Vielen Dank!


----------



## TryToHelp (1. Nov 2012)

Ist nur mal schnell dahingeschrieben, aber so oder so ähnlich könnte es funktionieren ;-)

```
public List<Datenknoten> datenknotenGeben(Datenelement suchinhalt){
        List<Datenknoten> result=new ArrayList<Datenknoten>();
        return datenknotenGeben2(suchinhalt,result);
    }

public List<Datenknoten> datenknotenGeben2(Datenelement suchinhalt,List<Datenknoten>result){
        if(inhalt.istGleich(suchinhalt)){
            result.add(this);
        }
        return result.add(naechster.datenknotenGeben(suchinhalt));
    }
```

Ich hoffe es inspiriert dich


----------



## SlaterB (1. Nov 2012)

@Wave
das einzige was ich im Sinn habe ist dein Lernerfolg,
was fertiger Code ohne Denkbeteiligung bringt weiß ich ganz genau, 
nächste Woche die nächste Frage, ohne etwas gelernt zu haben, bis man sich irgendwann nicht mehr durchmogeln kann

mein Stil kann dir missfallen, ein anderer ist mir nicht möglich,
die Aussagen sollten dir aber zu denken geben, etwa vor der Suche in einer eigenen Liste erstmal gedanklich durchdringen, dass da eine Liste vor dir liegt


----------



## Landei (1. Nov 2012)

Wave hat gesagt.:


> Lieber SlaterB,
> 
> bei allem Respekt:
> du warst auch Anfänger! Ich tue mich schwer, wenn wir die Liste (mit Kompositum aufgezogen) gerade lernen und hier nun ein DANKBARER Tipp mit fertigen "List" kommt, was bei mir (noch) nicht behandelt wurde.
> ...



Slater _hat_ versucht, dir zu helfen, du hast es nur nicht verstanden. Lies es einfach noch einmal langsam und unvoreingenommen durch. Es muss bei _dir_ klick machen, nicht bei uns, und das musst du dir auch selbst erarbeiten. Wenn von dir gefordert wird mitzudenken, ist das nicht zu viel verlangt, und nichts was Slater gesagt hat, geht über deinen Wissensstand hinaus. 

Es ist richtig, dass man manchmal "blockiert" ist und den Wald vor Bäumen nicht sieht, aber das gehört einfach zum Programmieren dazu, genauso wie mit aller Kraft zu versuchen, die Blockade zu überwinden.


----------



## Wave (1. Nov 2012)

Danke für deine Inspiration.
Ich habe nun folgendes gemacht:

Klasse LISTENELEMENT:

```
...
public abstract List <Datenknoten> datenknotenGeben3(Datenelement suchinhalt, List<Datenknoten> result);
...
```

Klasse ABSCHLUSS:


```
...
public abstract List <Datenknoten> datenknotenGeben3(Datenelement suchinhalt, List<Datenknoten> result){
        return null;
    }
...
```


Klasse DATENKNOTEN:

```
...
public List<Datenknoten> datenknotenGeben3(Datenelement suchinhalt, List<Datenknoten> result){
        if(inhalt.istGleich(suchinhalt)){
            result.add(this);
        }
        else{
            return result.add(naechster.datenknotenGeben3(suchinhalt, result));
        }
    }
...
```

Klasse SORTIERTELISTE:

```
...
public List<Datenknoten> datenknotenGeben2(Datenelement suchinhalt){
        List<Datenknoten> result = new ArrayList<Datenknoten>();
        return erster.datenknotenGeben3(suchinhalt, result);
    }
...
```

In der Klasse DATENKNOTEN kommt nun die Fehlermeldung "no suitable method found for add(java.util.List<Datenknoten>).
Was bedeutet das?


----------



## TryToHelp (1. Nov 2012)

Dein Problem ist jetzt

Du hast als resultat eine Liste mit Datenknoten 
	
	
	
	





```
List <Datenknoten>
```
 dem versuchst du jetzt aber anstelle eines Datenkonoten, eine Liste von Datenknoten hinzuzufügen, was natürlich nicht gehen kann, da du ja nicht eine Liste von Listen hast sondern von Datenknoten.

Ich hatte da nicht ordentlich drüber nachgedacht, war ja auch nur als insperation gedacht, nicht als Lösung ;-)

Wie gesagt, du willst, eine Liste aus Datenknoten erstellen, du musst dir anschauen, wie du die findest, bzw wie du die nächsten findest und diese der Liste hinzufügen und nicht wie es momentan ist, einfach alles eins zu eins reinkopieren ;-)


----------



## TryToHelp (1. Nov 2012)

```
public List<Datenknoten> datenknotenGeben(Datenelement suchinhalt){
        List<Datenknoten> result=new ArrayList<Datenknoten>();
        return datenknotenGeben2(suchinhalt,result);
    }
 
public List<Datenknoten> datenknotenGeben2(Datenelement suchinhalt,List<Datenknoten>result){
        if(inhalt.istGleich(suchinhalt)){
            result.add(this);
        }
        List<Datenknoten> result2=naechster.datenknotenGeben(suchinhalt);
        for (Datenknoten dk:result2){
            result.add(dk);
            }
        return result;
    }
```


----------



## SlaterB (1. Nov 2012)

nur so nebenbei

```
List<Datenknoten> result2=naechster.datenknotenGeben(suchinhalt);
        for (Datenknoten dk:result2){
            result.add(dk);
            }
```
==

```
result.addAll(naechster.datenknotenGeben(suchinhalt));
```

die Auftrennung in verschiedene Methoden ist etwas fragwürdig, neue Listen ständig auch nicht zwingend,
eine Rekursions-Methode, Liste als Parameter, in jedem Durchlauf entweder den eigenen Eintrag einfügen oder nicht + weiteren Aufruf,
kein Rückgabewert, kein addAll() dann mehr

----

bzw. ohne Parameter mit Rückgabewert Liste,
nur der letzte Aufruf für das Endelement erzeugt eine leere Liste, diese als Rückgabe, 
jeder weitere fügt ein, gibt auch diese Liste zurück,

das als Inspiration für Rekursions-Varianten


----------



## TryToHelp (1. Nov 2012)

@SlaterB, ja da hast du recht, wie gesagt, war nur mal schnell getippt, als insperation, also um eine Idee zu bekommen, war nicht als Lösung und erst recht nicht als DIE LÖSUNG gedacht ;-)


----------



## Wave (1. Nov 2012)

Hab nun weiterhin probiert. Es funktioniert nun...? Anbei von BlueJ die Bilder aus dem Objektinspektor. Ich kann die Objekte "aufrufen", nach denen ich gesucht habe.

Was bedeutet private int size und private int modcount beim Objektinspektor?

Danke für die Hilfen.


----------



## SlaterB (1. Nov 2012)

size ist ja noch verständlich, die ArrayList muss wissen, wie viel vom Array befüllt ist,
da auch null gespeichert werden kann, ist es nicht aus dem Array abzulesen, sonst zu aufwendig

modcount wird dann sehr speziell in der Implementierung, von AbstractList 
AbstractList (Java Platform SE 6)


> protected transient int modCount
> 
> The number of times this list has been structurally modified. Structural modifications are those that change the size of the list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.
> 
> ...


----------

