Konstruktor richtig implementiert? Frage zu Benutzereingaben...

Funktionierdochmal

Bekanntes Mitglied
Hi!
im Hauptprogramm kann der Benutzer so viele Rechnung anlegen, bis er "" eingibt. Aber mein Konstruktor hat keine Parameter und wie kann ich abhängig von der Häufigkeit aller Benutzereingaben, ständig neue "rechnungen" erstellen?
Zum Verständnis habe ich unten den Teil markiert.
Meine Klassen Rechnung und Kasse (Hauptprogramm):
Java:
package kasse;
import java.util.*;



public class Kasse {
    private static LinkedList<Rechnung> rechnungen;
    private static Warenlager<Ware> lager;
   
   
    public static void main(String[] args) {
       
        Scanner scan = new Scanner(System.in);
        boolean weiter = true;
        do {
            System.out.println("R: Lege neue Rechnung an.");
            System.out.println("Z: Gibt alle gespeicherten Rechnungen mit "
                + "Datum und Preis aus.");
            System.out.println("W: Fuege neue Ware zum Lager hinzu.");
            System.out.println("A: Gibt alle gespeicherten Waren im "
                + "Lager aus.");
            System.out.println("E: Das Programm wird beendet.");
            String auswahl = scan.nextLine();
            if (auswahl.equals("R")) {
                do {
                rechnungen.add(new Rechnung());
                } while()
Java:
package kasse;
import java.util.*;
import java.text.SimpleDateFormat;

public class Rechnung {
     
    private LinkedList<Ware> waren;
    private String datum;
   
    Scanner scan = new Scanner (System.in);
     
    SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yyyy");
     String date = DATE_FORMAT.format(datum);


    public Rechnung () {
        datum = date;
        waren = new LinkedList<Ware>();
       
       
    }
   
   
    public void addWare(Ware ware) {
       
        if (ware == null) {
            throw new IllegalArgumentException("Eingabe ist fehlerhaft!");
           
        } else {
            waren.add(ware);
        }
       
    }
   
    public double getPreis() {
        double summe = 0;
        for(Ware w: waren) {
            summe += w.getEinzelPreis();
        }
        return summe;
    }
   
   
   
    public String toString() {

        for (Ware w : waren) {
             System.out.println(w);
        }
        return date;
    }
   
   
   
   
   
   
   
   
   
   
   
   
   
   
    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}


upload_2019-2-1_21-3-50.png
upload_2019-2-1_21-4-10.png
 
Wenn der Anwender R eingegeben hat, soll eine(!) Rechnung erfasst werden. Dazu werden so lange Artikelnummern (id) eingelesen, bis der Anwender die Erfassung mit einer Leerzeile beendet. Falls es zur eingelesenen Artikelnummer im System einen Artikel gibt, soll dieser zur Rechnung hinzugefügt werden.

Du dagegen gehst nach der Eingabe von R in eine Endlosschleife, in der Du eine (leere) Rechnung nach der anderen erstellst.
 
die schleife, die bis zu einer leeren eingabe laufen würde würde ja so sein:
do {
...
} while(variable=="");

aber wie erstelle ich abhängig von der Anzahl, wie oft der Benutzer eine ID eingibt, eine neue Variable dafür?
 
Du liest die Eingabe vom Benutzer ein. Ist sie nicht leer, wandelst Du die Eingabe in eine Zahl um. Diese Zahl ist dann die id der Ware. Das zugehörige Warenobjekt holst Du Dir aus dem Warenlager und fügst es der Rechnung hinzu.
 
Java:
                String eingabe = scan.nextLine();
               
                while(eingabe!="") {
                int result = Integer.valueOf(eingabe);
                rechnungen.add(new Rechnung());
                eingabe = scan.nextLine(); 
                }
Also den ersten Teil habe ich. Aber ich soll ein Objekt aus dem Warenlager "holen"? Wie genau kann ich mir das vorstellen?

Ware:
Java:
public class Warenlager<ware> implements Iterator<ware> {
   
    //Warenlager Iterator: "ListIterator<String> iterator = list.listIterator();" ?

   
    private List<Ware> waren;
   
   
    public Ware addWare(Ware ware) {
       
       
        if (ware == null) {
            throw new IllegalArgumentException("Eingabe ist fehlerhaft!");
           
        } else {
            //Überschreiben bei selber ID ? 
            for(Ware w: waren) {
                if (ware.getID() == w.getID()) {
                   
                }
                   
        }
        }
        return ware;
    }
   
    public Ware getWare(int id) {
        Ware nurAusgabe = null;
        for (Ware w: waren) {
            if (id == w.getID()) {
                nurAusgabe = w;
            } else {
                return null;
            }
        }
        return nurAusgabe;
    }

    public boolean hasNext() {
        // TODO Auto-generated method stub
        return false;
    }

    public ware next() {
        // TODO Auto-generated method stub
        return null;
    }
}
 
Schau Dir mal die Aufgabenstellung an: es geht darum, dass Du geeignete Datenstrukturen aus java.util verwenden sollst. Im UML-Diagramm siehst Du, dass bei einigen Beziehungen {ordered} dabeisteht und bei anderen nicht. Das darfst Du ruhig als Hinweis verstehen.

Das Vorhandensein dieser Eigenschaft bedeutet, dass Du eine Datenstruktur verwenden musst, die das Einhalten einer - wie auch immer gearteten - Ordnung erlaubt. Hier bietet sich meist eine Liste (java.util.List) an.

Beim Warenlager ist es etwas anders. Es spielt keine Rolle, in welcher Reihenfolge die Waren hinzugefügt werden. Das Warenlager ist eine Menge von Waren, ein Warenobjekt kann nur einmal vorhanden sein. Hinzu kommt, dass es eine ID gibt, die jedes Warenobjekt eindeutig identifiziert. Das Warenlager soll anhand der ID das zugehörige Warenobjekt zurückgeben. Insgesamt hat es die typische Eigenschaft eines Dictionaries, nämlich ungeordnete Schlüssel-Werte-Paare abzubilden (Schlüssel ist die ID, der Wert ist die Ware). Folglich verwendest Du im Warenlager für Deine waren nicht java.util.List sondern java.util.Map. Dann werden Deine Methoden alle sehr, sehr einfach 😉

Zum Code in der Kasse:
Code:
while(eingabe!="") {
Die Variable eingabe ist eine Referenz auf ein Objekt vom Typ String und Objekte vergleicht man inhaltlich nicht mit "==" bzw. !=. Strings stellen zwar in gewisser Hinsicht einen Sonderfall dar, das sollte Dich aber nicht interessieren. Außerdem kann eingabe auch null sein. Schreib besser:
Code:
while (istNichtLeer(eingabe)) {
und eine kleine Methode
Java:
static boolean istNichtLeer(String str) {
    return str != null && !str.isEmpty();
}

Dann:
Code:
                rechnungen.add(new Rechnung());
Du musst Dir die erstellte Rechnung schon merken, Du willst ja noch Waren hinzufügen.
Java:
Rechnung rechnung = new Rechnung(); 
...
while (istNichtLeer(eingabe)) { {
    ...
}
// an der Stelle ist die Eingabe von Rechnungspositionen abgeschlossen
rechnungen.add(rechnung);
 
Java:
            if (auswahl.equals("R")) {
                System.out.println("Bei leerer Eingabe wird abgebrochen.");
                Rechnung rechnung = new Rechnung(); 
                System.out.println("Gebe ID (Ganzzahl) ein: ");
                String eingabe = scan.nextLine();
               
                while(istNichtLeer(eingabe)) {
                    int result = Integer.valueOf(eingabe);
                    if (result%2 == 0) {
                        System.out.println("Jetzt Beschreibung und Preis"
                            + " der Ware bitte:");
                        String name = scan.nextLine();
                        double preis = scan.nextDouble();
                        Ware ware = new Ware(result, name, preis);

                        rechnung.addWare(ware);
                        System.out.println("Neue Ware wurde der Rechnung"
                            + " hinzugefuegt.");
                    } else {
                        System.out.println("Fehlerhafte Eingabe!");
                    }
                   
                eingabe = scan.nextLine(); 
                }
                System.out.println("Rechnung fertiggestellt.");
                rechnungen.add(rechnung);
Habe den Code (dank dir) soweit sinnvoll implementiert. Ich verstehe diese ganze Map/HashMap-Sache nur nicht... versuche mich da mal reinzulesen..
 
Ich verstehe diese ganze Map/HashMap-Sache nur nicht...
Eine Map verwaltet eine Menge von Schlüssel-Werte-Paaren. Dabei sind Schlüssel per Definition eindeutig, d. h. zu einem Schlüssel existiert höchstens ein Schlüssel-Werte-Paar in der Map.

Willst Du beispielsweise einen Kunden über die Kundennummer ermitteln, kannst Du eine Map verwenden. Der Schlüssel ist dann die Kundennummer, der Wert der dazugehörige Kunde.

Du kannst auch alle Einträge einer Map erhalten. Das sind dann eben Schlüssel-Werte-Paare, die als Map.Entry-Objekt zurückgegeben werden. Dabei ist keine Ordnung definiert, d. h. eine Map sichert im Allgemeinen keine bestimmte Reihenfolge zu, in der sie die Einträge zurückgibt. Wird eine solche Zusicherung benötigt, kann man auf SortedMap ausweichen.

Eine HashMap ist nun einfach eine konkrete Implementierung einer Map. Sie verwendet - wie der Name schon sagt - Hashing. Dabei wird direkt aus dem Schlüssel die Position berechnet, an der sich der zugehörige Eintrag befinden müsste. Daher haben HashMaps keine Ordnung und sind in der Regel sehr schnell.

Statt über Hashing könnte man eine Map aber z. B. auch mittels eines Baumes implementieren. Eine solche Implementierung bietet Java ebenfalls an: TreeMap. Eine TreeMap implementiert eine SortedMap - d. h. hier unterliegt die Rückgabe der Schlüssel-Werte-Paare einer Ordnung.

Details findest Du wie immer in den JavaDocs.
 

Zurück
Oben