Wer kann mir helfen bei dieser Obstkorb Aufgabe in Java (Siehe Foto und mein code)?

2 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

1) Wenn der Parameter, der an den Konstruktor übergeben wird, die Anzahl an Obstsorten darstellen soll, ist diese Zeile logisch betrachtet falsch.

int[] arrayobstsorten = {anzahlObstsorten};

So legst du lediglich ein Array an, welches einen Wert besitzt - den von anzahlObstsorten.

Stattdessen solltest du ein Array anlegen, welches die gegebene Anzahl an Elementen besitzt.

int[] arrayobstsorten = new int[anzahlObstsorten];

2) Gibt es einen Grund, wieso du hier:

for(int i = 0; i<arrayobstsorten.length-1; i++) {

angibst, das letzte Element auslassen zu wollen? Wenn du alle Elemente durchlaufen möchtest, muss der Vergleichsoperator geändert werden oder du subtrahierst nicht mit 1.

3) Eine Obstsorte definiert sich durch eine gewisse Anzahl und einen Preis. Erstelle dazu doch eine neue Klasse:

class Fruit {
  // ...
}

die die erwähnten Attribute trägt. Dies macht deinen Code auch einfacher und kompakter - du musst nicht mit verschiedenen Arrays hantieren.

4) In deiner zweiten Schleife:

if (j == 0) {
  obstsortenpreis[j] = (anzahlObstsorten - j) * 1;
}

obstsortenpreis[j] = (anzahlObstsorten - j) * j;  

gibt es doch eigentlich keinen Grund für das if, oder doch? Selbst wenn, würde bei j = 0 erst die Anweisung innerhalb der Klammern ausgeführt und danach der Wert wieder überschrieben werden.

5) Vergleiche die Aufrufe der Aufgabe mit deinen Implementationen. Du hast bei deinen Methoden Rückgabewerte definiert, obwohl sie doch gar nicht gebraucht werden.

Zu deinem Problem:

Schau dir nochmals deine Methoden an und vergleiche mit den vorgegebenen Aufrufen der Aufgabe. Werden sie über den Klassennamen oder die Instanz k aufgerufen? Sind sie bei dir objektgebunden oder klassengebunden?


Nichtsnutz12 
Beitragsersteller
 19.02.2019, 20:40

HEj kannst du mir helfen, ich hab mir ja jetzt 2D Arrays beigebracht und wollte die selbe aufgabe nochmal programmieren diesmal mit 2D Array und das hab ich mehr oder weniger geschafft doch scheinbar hab ich den array nicht richtig befüllt deswegen hab ich vorhin die extra frage gestellt jedenfalls wollt ich halt 2 spalten die erste 20-1 und die zweite 1-20 wo liegt mein Fehler die Printumsatz Methode gibt leider falsche werte aus Hier mein Code:

https://pastebin.com/gYeBMeaD

0
regex9  19.02.2019, 22:20
@Nichtsnutz12

Aber wieso ignorierst du wieder all die Verbesserungsvorschläge, die dir hier schon bei all deinen Fragen gegeben wurden (Code-Konventionen) ...😖

Du hast ein Array mit den Dimensionen [20][2]. Bildlich:

[
  [ 0, 0 ],
  [ 0, 0 ],
  [ 0, 0 ],
  [ 0, 0 ],
  // etc. ... in general 20 rows
]

Deine äußere Schleife läuft über jede einzelne Reihe. Daher greifst du ja auch mit i auf den ersten Indexer zu:

array[i][...]

Je Reihe läuft deine innere Schleife durch die Elemente des aktuellen Arrays - also die Spalten. Hierfür verwendest du den Zähler j. Der Wertebereich für j liegt demnach bei { 0, 1 }.

Nun rechne einmal aus:

20 - j mit j = { 0, 1 }
j + 1 mit j = { 0, 1 }

Das if davor, verhält sich übrigens genauso, wie ich es dir weiter oben schon einmal erklärt habe.

1
Nichtsnutz12 
Beitragsersteller
 20.02.2019, 10:18
@regex9

hmm oke also j ist halt nur 0 und 1 wie wärs denn wenn ich bei j die Abbruchbedingung "j<array.length" mache dann würde es ja von 0 bis 20 laufen also hab ich jetzt mal gemacht aber geholfen hat das nix hmmm

0
Nichtsnutz12 
Beitragsersteller
 20.02.2019, 10:49
@Nichtsnutz12

habs hinkegriekt hab halt einfach für j i genommen jetzt wurde es richtig befüllt! Was ich aber noch nicht gemacht hab ist, das bei den main aufrufen verkaufe(1,1) steht das wäre ja bei mir schon die zweite Sorte, ich muss also Index 0 irgendwie eliminieren und bis Index 20 laufen lassen ahhaje keine Ahnung wie das gehen soll

0
regex9  20.02.2019, 13:03
@Nichtsnutz12

Schau dir nochmal die bildliche Array-Darstellung oben an. Die innere Schleife läuft über ein Element wie dieses:

[ 0, 0 ]

Das hat nur zwei Elemente. Die Variable j wird folgend genutzt, um auf diese Elemente zuzugreifen:

arr[i][j]

Wenn es nun einen Index anspricht, der weit über den Rahmen (2 Elemente > 0, 1) geht, wirst du auf einen Fehler stoßen.

1
Nichtsnutz12 
Beitragsersteller
 21.02.2019, 00:54
@regex9

Es ist vollbracht... ich bin offiziell durchgefallen.... tschüss für immer...

0
Nichtsnutz12 
Beitragsersteller
 03.02.2019, 18:05

1) ok hab ich korrigiert

2) soweit ich weiß beginnen ja Arrays bei dem Index 0, das heißt wenn wie im Beispiel 20 die anzahlObstsorten ist, müsste ja das array von 0-19 gehen. Deswegen die -1, weil 20 wäre out of Index oder verwechselt ich was??

3)hmm ok ich werde versuchen und mich später mit dem Ergebnis melden

4) ehmmm doch, weil ich will ja da den Preis festlegen und angenommen (anzahlObstsorten - 0)* 0 ergibt ja die 0 da wär der Preis ja 0€ was ja Unsinn ist, deswegen für das erste Element wollt ich das halt damit verhindern.

5) Hmm das versteh ich noch immer nicht ganz also bei der aufgabe steht ja im Beispiel verkaufe(1,2), das sind ja die Werte die in die Methode reinmüssen sonst würde das ja nicht funktionieren deswegen hab ich da halt int und int genommen, wenn das leer wäre also verkaufe() hätte ich void genommen mehr Auswahl gibts ja auch nicht so hätt ich das jetzt verstanden? Weil bei einer void Methode können die ja dann nix reinlegen oder also wenn ich es zu void verkaufe ändere würde" verkaufe(2,3)" aus dem Beispiel nicht klappen? Meinst du das?

Mit freundlichen Grüßen

0
regex9  03.02.2019, 18:21
@Nichtsnutz12

2) Die Bedingung bei dir läuft so lange, wie j, beginnend bei 0, kleiner als seine Länge - 1 ist. Die Länge des Arrays sollte bei 20 liegen. Dem die 1 abgerechnet ergibt 19. Die Schleife läuft nun von 0 bis 18. Wenn j den Wert 19 erreicht, bricht die Schleife ab, da die Bedingung nicht mehr erfüllt wird.

Hier zum Testen: https://ideone.com/2Sjrs5

4) Ah, ich hab das letzte Zeichen nicht richtig gelesen. Dennoch überschreibst du den Wert gleich wieder.

Zum Ausprobieren: https://ideone.com/VsdZBi

5) Das klingt wirr. Der Rückgabewert hat nichts mit den Parametern zu tun.

Um in einen Methodenkontext Werte hineinzugeben, gibt es Parameter. Um aus dem Kontext wieder einen Wert herauszubekommen, gibt es Rückgabewerte.

Die Methode müsste bei dir so aussehen:

public void verkaufe(int sorte, int anzahl) {
  // sell something ...
}
1
Nichtsnutz12 
Beitragsersteller
 03.02.2019, 18:57
@regex9

2) ok hab ich korrigiert

4) hmmm komisch warum wird er überschrieben? Ich mein es ergibt ja Sinn: j[0] = (20 - 1) * 1 wäre j[0] = 19 (merke grad bei 20-j hätte 20-1 hingemusst habs korrigiert deswegen 19 als Ergebnis), dann j[1] = (20-2)*2 = 36, also j[1] = 36, dann j[2] = (20-3)*3 = 51 usw.... warum wird das denn immer überschrieben versteh ich jetzt nicht also bei dem Testprogramm von dir wird's tatsächlich überschrieben hmm komisch hätte keine Idee ):

5) ohh ahsooo okaaayyy das ist mir jetzt auch neu😅😅😅 ok werd ich mir mal merken und korrigieren 😅😅

0
regex9  03.02.2019, 19:08
@Nichtsnutz12

Ein vereinfachendes Beispiel zum Nachvollziehen:

int value = 0;

if (value == 0) {
  value = 1;
}

value = 2;

Erst wird die Variable initialisiert, danach geht der Programmfluss weiter in das if. Der Wert wird neu definiert, der Programmfluss geht aus if raus und dann weiter.

Anders wäre es, wenn du bspw. if-else einsetzen würdest:

int value = 0;

if (value == 0) {
  value = 1;
}
else {
  value = 2;
}

Innerhalb der Schleife wäre ebenfalls continue eine Option:

int value = 0;

for (int i = 0; i < 20; ++i) {
  if (i == 0) {
    value = 1;
    continue;
  }

  value = 2;
}
1
Nichtsnutz12 
Beitragsersteller
 03.02.2019, 19:29
@regex9

hmm ok danke ich hab else eingesetzt also nur else hinten dran hoffe es überschreibt sich nicht mehr

0
Nichtsnutz12 
Beitragsersteller
 04.02.2019, 21:25
@regex9

Ich hab es scheinbar tatsächlich hingekriegt aber die Umsatz Methode spackt rum und liefert falsche werte kann jemand erklären wieso? Hier mein Code der mehr oder weniger funktionieren müsste:

https://pastebin.com/NLPu5Re7

0
regex9  04.02.2019, 23:31
@Nichtsnutz12

Da passt so einiges noch nicht...

Also zuerst, was lässt sich aus dem Aufgabentext herausziehen:

  • Ein Obstkorb hat Platz für eine gewisse Anzahl an Obstsorten (diese Zahl wird über den Konstruktor mitgegeben)
  • Jede Sorte hat eine gewisse Eigenanzahl sowie einen nicht negativen, ganzen Preis
  • Anzahl und Preis jeder Sorte werden initial automatisch gesetzt (Anzahl von Sortenanzahl absteigend, Preis von 1 an aufsteigend)
  • Es gibt eine Methode verkaufe(sorte, anzahl), die einen Fehler ausgibt, wenn es nicht mehr genügend von der gewünschten Sorte zu verkaufen gibt.
  • Es gibt eine Methode neuerPreis(sorte, preis), der Preis muss positiv sein
  • Es gibt eine Methode, die den Umsatz an verkauftem Obst ausgibt.

Aus dieser Beschreibung lässt sich ein objektorientiertes System beschreiben (Objektdiagramm). Es gibt zwei Objekttypen, die miteinander in einem Verhältnis stehen: Obstkorb und Obstsorte. Eine Obstsorte hat zwei Eigenschaften: Sie kann durch eine Anzahl beziffert werden sowie durch einen Preis. Der Obstkorb hat unterschiedliche Sorten und verwaltet sie in gewisser Weise.

Folglich kann die erste Klasse folgendermaßen aussehen:

class Fruit {
  private int count;

  private int price;

  public Fruit(int price, int count) {
    this.count = count;
    this.price = price;
  }

  public int getCount() {
    return count;
  }

  public int getPrice() {
    return price;
  }

  public void setCount(int count) {
    this.count = count;
  }

  public void setPrice(int price) {
    if (price >= 0) {
      this.price = price;
    }
  }
}                                

Wie du siehst, fasst dies die Eigenschaften, die du bisher noch via Arrays hältst, zusammen. Dies ist zum einen logisch besser nachvollziehbar, flexibler (du kannst schnell neue Eigenschaften / Methoden hinzufügen) und sicherer (derzeit musst du noch darauf achten, dass keines deiner Arrays überläuft und bei synchron zueinander bleiben).

Die Klasse für den Obstkorb hat folgend zwei Eigenschaften: Einmal ein Array für die Obstsorten und einmal ein Attribut für den Umsatz. Nichts, absolut nichts davon ist statisch! Das Gleiche gilt für alle Methoden. Sie und die Attribute beschreiben den Zustand eines Objektes. Wenn ein Obstkorb erstellt wird, dann hat er seinen eigenen Umsatz, seine eigene Anzahl an Obstsorten, etc.. Er teilt es in keinster Weise mit anderen Instanzen seines Typs.

class FruitBasket {
  private Fruit[] fruits;

  private int sales;
}

Nun folgen die einzelnen Methoden sowie der Konstruktor.

public FruitBasket(int numberOfVariousSorts) {  
  fruits = new  Fruit[numberOfVariousSorts];
  sales = 0;

  for (int i = 0, price = 1; i < fruits.length; ++i, ++price) {
    fruits[i] = new Fruit(price, numberOfVariousSorts - i);
  }
}

Das Setzen des Preises und der Anzahl an Sorten lässt sich in einem Zug, in einer Schleife realisieren.

Beim Verkaufen einer Sorte musst du darauf achten, deren Preis einzubeziehen. Du machst das bei dir gar nicht, sondern änderst den Preis sogar.

public void sell(int sort, int count) {
  Fruit fruitToSell = fruits[sort - 1];

  if (fruitToSell.getCount() - count < 0) {
    System.out.println("Es gibt nicht mehr genug von dieser Sorte.");
    return;
  }

  fruitToSell.setCount(fruitToSell.getCount() - count);
  sales += count * fruitToSell.getPrice();
}

Das Neusetzen des Preises ist in der dazugehörigen Methode ein Einzeiler:

fruits[sort - 1].setPrice(price);

und das Ausgeben des Umsatzes zu trivial, um erwähnt zu werden.

Zuletzt muss nur noch die Main-Klasse mit ihrer Methode main implementiert werden. Halte diese Methode nach Möglichkeit stets in einer separaten Klasse, denn von der Logik her hat sie in einem Obstkorb bspw. ja eigentlich nichts zu suchen. Ich selbst füge die Methode nur in solche Minianwendungen ein, wenn es darum geht, etwas schnell zu testen.

1
Nichtsnutz12 
Beitragsersteller
 05.02.2019, 12:23
@regex9

hmm oke danke aber ne ich ändere den Preis nicht beim Verkaufen, ich zieh bloß das Geld halt davon ab. hmm naja egal BB ich hab professionelle Nachhilfe bestellt damit ich nicht durchfalle Start ist am Donnerstag.....

0
Also du deklarierst die arrays schon mal falsch. So hast du ein Array der Länge 1 mit array[0]=Anzahlobstsorten. richtig wäre 
int[] arrayobstsorten = new int[AnzahlObstsorten];

Schau dir bitte nochmal an, wie man mit arrays arbeitet. Die Schleife müsste z.B. von

i=0; i < arra.length; i++ laufen (ohne das -1)

Woher ich das weiß:Studium / Ausbildung

user2362h6  05.02.2019, 12:52

Wo kommt die Warnung mit static? Kannst auch probieren überall (Variablen und Methoden) das static zu entfernen. Dann sind es Objektmethoden/variablen anstatt Klassenmethoden

1
user2362h6  04.02.2019, 22:41

versuch mal das hier:

https://pastebin.com/tydAYJk8

das Feld für den preis wurde glaub ich nicht richtig initialisiert und die Methode neuerPreis dementsprechend auch nicht

1
Nichtsnutz12 
Beitragsersteller
 05.02.2019, 12:24
@user2362h6

hmm ok danke ej die andere Antwort meckert das static da nichts verloren hat.... ):

0
user2362h6  04.02.2019, 19:48

Stimmt. Du musst direkt unter Public class Obstsorten{

private int[] arrayobstsorten;

als klassenvariable deklarieren. (Im konstruktor anschließend das int[] streichen. Und dasselbe mit dem anderen Array. Ich kann dir das Buch „Java ist auch eine Insel“ empfehlen. Da ist die Programmiersprache verständlich und ausführlich erklärt. Den Inhalt einer älteren Auflage des Buches gibt es auch gratis als Website im Internet

1
Nichtsnutz12 
Beitragsersteller
 04.02.2019, 21:24
@user2362h6

Ich hab es scheinbar tatsächlich hingekriegt aber die Umsatz Methode spackt rum und liefert falsche werte kann jemand erklären wieso? Hier mein Code der mehr oder weniger funktionieren müsste:

https://pastebin.com/NLPu5Re7

0
user2362h6  03.02.2019, 22:41

Gewöhne es dir lieber mit < Array.length an.

in der verkaufen Methode sollte noch eine if abfrage sein (ob genug Obst der Sorte vorhanden sind)

1
Nichtsnutz12 
Beitragsersteller
 04.02.2019, 19:41
@user2362h6

jo danke leider wird arrayobstsorten in der Verkaufsmethode nicht erkannt da steht man muss lokale Variable anlegen....

0
user2362h6  03.02.2019, 18:35

das ist richtig, aber bei i=20 ist die Bedingung (i<Array.length) nicht mehr erfüllt und dadurch wird die Schleife beendet

1
Nichtsnutz12 
Beitragsersteller
 03.02.2019, 18:06

hmm aber wenn das array 20 groß ist der Index ist ja aber nur 0-19 das heisst -1 weil 20 wäre out of Index

0
Nichtsnutz12 
Beitragsersteller
 03.02.2019, 18:09
@Nichtsnutz12

ok hab ich korrigiert hast recht gehabt -1 kann weg fallen ok was jetzt? Wie krieg ich die restlichen Methoden hin=

Mit freundlichen Grüßen

0