15.1 Arrays

Aufgabe

Aufgabe 15-1: Halbjahresleistung IV

In den Aufgaben Aufgabe 8-2 und Aufgabe 9-7 haben wir ein Programm erstellt, mit dessen Hilfe die Noten, die ein Schüler in einem Fach erzielt hat, erfasst und der entsprechende Notendurchschnitt sowie die daraus resultierende Zeugnisnote berechnet werden können. Aus Vereinfachungsgründen werden in dem Programm ausschließlich die Noten erfasst, nicht jedoch das betroffene Fach beziehungsweise der Name des jeweiligen Schülers.

Eine zusätzliche Vereinfachung war die Annahme, dass in jedem Fach stets zwei Klassenarbeiten geschrieben und eine Note für die mündliche Leistung vergeben werden. Diese Einschränkung wird nun aufgehoben. Das Programm soll nun vom Benutzer die Anzahl der Klassenarbeiten und die Anzahl der mündlichen Noten erfragen, diese anschließend erfassen und abschließend den Notendurchschnitt sowie die Zeugnisnote ausgeben.

Die Ein- und Ausgabe der Daten soll weiterhin über die Konsole erfolgen (vgl. Abb. 15-1).

Konsole
Halbjahresleistung
==================

Bitte geben Sie die Anzahl der Klassenarbeiten
und die Anzahl der mündlichen Noten ein:

 Anzahl der Klassenarbeiten: 4
 Anzahl der mündlichen Noten: 2

Bitte geben Sie die jeweiligen Noten ein:

 Note 1. Klassenarbeit: 13
 Note 2. Klassenarbeit: 10
 Note 3. Klassenarbeit: 11
 Note 4. Klassenarbeit: 8

 1. Mündliche Note: 9
 2. Mündliche Note: 12

----------------------------------------------

Notendurchschnitt: 10.5
Zeugnisnote: gut
Abb. 15-1: Konsole mit Benutzereingaben (Beispieldaten)
Aufgaben
  1. Informieren Sie sich mit Hilfe des folgenden Beispiels über Arrays in Java. Erstellen Sie anschließend auf Grundlage des UML-Klassendiagramms (vgl. Abb. 15-4) den Quellcode der Klasse Noten. Lösung
    Lösung
    JAVA
    package app;

    public class Halbjahresleistung {

        private int[] notenKlArb;
        private int[] notenMuendlich;

        public Halbjahresleistung (int pAnzahlKlArb, int pAnzahlMuendlich) {
            notenKlArb = new int[pAnzahlKlArb];
            notenMuendlich = new int[pAnzahlMuendlich];

            for(int i=0; i<notenKlArb.length; i=i+1) {
                notenKlArb[i] = -1;
            }

            for(int i=0; i<notenMuendlich.length; i=i+1) {
                notenMuendlich[i] = -1;
            }
        }

        public int addNoteKlArb(int pNote) {
            int index = -1;

            for(int i=0; i<notenKlArb.length; i=i+1) {
                if(notenKlArb[i] == -1) {
                    notenKlArb[i] = pNote;
                    index = i;
                    break;
                }
            }

            return index;
        }

        public void setNoteKlArb(int pIndex, int pNote) {
            notenKlArb[pIndex] = pNote;
        }

        public int getNoteKlArb(int pIndex) {
            return notenKlArb[pIndex];
        }

        public void removeNoteKlArb(int pIndex) {
            notenKlArb[pIndex] = -1;
        }

        public int ermittleAnzahlNotenKlArbMax() {
            return notenKlArb.length;
        }

        public int ermittleAnzahlNotenKlArb() {
            int anzahl=0;

            for(int i=0; i<notenKlArb.length; i++) {
                if(notenKlArb[i]!=-1) {
                    anzahl++;
                }
            }

            return anzahl;
        }

        public double berechneSchnittNotenKlArb() {
            double schnitt;
            int summe = 0;
            int anzahl = 0;

            for(int i=0; i<notenKlArb.length; i++) {
                if(notenKlArb[i]!=-1) {
                    summe = summe + notenKlArb[i];
                    anzahl++;
                }
            }

            schnitt = (double)summe / anzahl;

            return schnitt;
        }

        public int addNoteMuendlich(int pNote) {
            int index = -1;

            for(int i=0; i<notenMuendlich.length; i=i+1) {
                if(notenMuendlich[i] == -1) {
                    notenMuendlich[i] = pNote;
                    index = i;
                    break;
                }
            }

            return index;
        }

        public void setNoteMuendlich(int pIndex, int pNote) {
            notenMuendlich[pIndex] = pNote;
        }

        public int getNoteMuendlich(int pIndex) {
            return notenMuendlich[pIndex];
        }

        public void removeNoteMuendlich(int pIndex) {
            notenMuendlich[pIndex] = -1;
        }

        public int ermittleAnzahlNotenMuendlichMax() {
            return notenMuendlich.length;
        }

        public int ermittleAnzahlNotenMuendlich() {
            int anzahl=0;

            for(int i=0; i<notenMuendlich.length; i++) {
                if(notenMuendlich[i]!=-1) {
                    anzahl++;
                }
            }

            return anzahl;
        }

        public double berechneSchnittNotenMuendlich() {
            double schnitt;
            int summe = 0;
            int anzahl = 0;

            for(int i=0; i<notenMuendlich.length; i++) {
                if(notenMuendlich[i]!=-1) {
                    summe = summe + notenMuendlich[i];
                    anzahl++;
                }
            }

            schnitt = (double)summe / anzahl;

            return schnitt;
        }

        public double berechneNotendurchschnitt() {
            return (3 * berechneSchnittNotenKlArb() + berechneSchnittNotenMuendlich()) / 4;
        }

        public String ermittleZeugnisnote() {
            String schulnote;
            double schnittGesamt = this.berechneNotendurchschnitt();

            if(schnittGesamt>=12.5) {
                schulnote = "sehr gut";
            }
            else if(schnittGesamt>=9.50) {
                schulnote = "gut";
            }
            else if (schnittGesamt>=6.5) {
                schulnote = "befriedigend";
            }
            else if (schnittGesamt>=3.5) {
                schulnote = "ausreichend";
            }
            else if (schnittGesamt>=0.5) {
                schulnote = "mangelhaft";
            }
            else {
                schulnote = "ungenügend";
            }

            return schulnote;
        }

    }
    Abb. 15-2: Klasse Werkzeug (Quellcode)
  2. Erstellen Sie den Quellcode der Klasse Benutzerkonsole (vgl. Abb. 15-1). Lösung
    Lösung
    JAVA
    package ui;

    import app.Halbjahresleistung;

    public class Benutzerkonsole {

        private Halbjahresleistung halbjahresleistung;
        
        public Benutzerkonsole() {
            this.erfasseDaten();
            this.zeigeDaten();
        }
        
        public void erfasseDaten() {
            ConsoleReader consoleReader = new ConsoleReader();
            
            int anzahlKlArb;
            int anzahlMuendlich;
            
            System.out.println("Halbjahresleistung");
            System.out.println("'=================\n");
            
            System.out.println("Bitte geben Sie die Anzahl der Klassenarbeiten\nund die Anzahl der mündlichen Noten ein:\n");
            
            System.out.print(" Anzahl der Klassenarbeiten: ");
            anzahlKlArb = consoleReader.nextInt();
            
            System.out.print(" Anzahl der mündlichen Noten: ");
            anzahlMuendlich = consoleReader.nextInt();
                
            System.out.println("\nBitte geben Sie die jeweiligen Noten ein:\n");
            
            halbjahresleistung = new Halbjahresleistung(anzahlKlArb,anzahlMuendlich);
            
            for(int i=1; i<=anzahlKlArb; i++) {
                System.out.print(" Note " + i + ". Klassenarbeit: ");
                halbjahresleistung.addNoteKlArb(consoleReader.nextInt());
            }
            
            System.out.println("");
            
            for(int i=1; i<=anzahlMuendlich; i++) {
                System.out.print(" " + i + ". Mündliche Note: ");
                halbjahresleistung.addNoteMuendlich(consoleReader.nextInt());
            }
                
        }
        
        public void zeigeDaten() {
            System.out.println("\n----------------------------------------------\n");
            System.out.println("Notendurchschnitt: " + halbjahresleistung.berechneNotendurchschnitt());
            System.out.println("Zeugnisnote: " + halbjahresleistung.ermittleZeugnisnote());
        }
        
    }
    Abb. 15-3: Klasse Benutzerkonsole (Quellcode)
img/Abb_15_4_UML_HalbjahresleistungIII.svg
app.Halbjahresleistung
Halbjahresleistung(int pAnzahlKlArb, int pAnzahlMuendlich)
Der Konstruktor erzeugt ein Array vom Typ int[] mit der Größe pAnzahlKlArb und weist dieses dem Attribut notenKlArb zu.
Anschießend erzeugt es ein zweites Array vom Typ int[] mit der Größe pAnzahlMuendlich und weist dieses dem Attribut notenMuendlich zu.
Zum Abschluss wird jedem Element der beiden Arrays der Wert -1 zugewiesen, um deutlich zu machen, dass diesem Element keine Note zugewiesen ist.
public int addNoteKlArb(int pNote)
Fügt pNote im Array noteKlArb an der ersten freien Stelle ein. Anschließend gibt es den Index dieser Stelle zurück. Besitzt das Array keine freie Stelle mehr, wird stattdessen der Wert -1 zurückgegeben.
public void setNoteKlArb(int pIndex, int pNote)
Im Array noteKlArbwird an die Stelle mit dem Index pIndex der Wert pNote geschrieben.
public int getNoteKlArb(int pIndex)
Aus dem Array noteKlArb wird der int-Wert (die Note) an der Stelle mit dem Index pIndex zurückgegeben.
public void removeNoteKlArb(int pIndex)
Im Array noteKlArbwird an die Stelle mit dem Index pIndex der Wert -1 geschrieben.
public int ermittleAnzahlNotenKlArbMax()
Gibt die Größe des Arrays noteKlArb zurück, das heißt die Anzahl der Noten, die maximal gespeichert werden können.
public int ermittleAnzahlNotenKlArb()
Gibt Anzahl der Elemente des Arrays noteKlArb zurück, deren Wert nicht -1 beträgt, und gibt diese zurück.
public double berechneSchnittNotenKlArb()
Berechnet den Durchschnitt aller im Array noteKlArb gespeicherten Elemente, deren Wert nicht -1 beträgt, und gibt diesen zurück.
Die Methoden, die den Zugriff auf das private Attribut notenMuendlich ermöglichen, verhalten sich analog zu denen, die den Zugriff auf das private Attribut notenKlArb ermöglichen
public double berechneNotendurchschnitt()
Berechnet den Gesamtnotenschnitt und gibt diesen zurück. Der Schnitt der Klassenarbeitsnoten wird dabei dreifach, der Schnitt der mündlichen Noten einfach gewichtet.
public String ermittleZeugnisnote
Ermittelt auf Grundlage des Gesamtnotenschnitts die Zeugnisnote. Mögliche Werte sind: "sehr gut", "gut", "befriedigend", ausreichend", "mangelhaft" und "ungenügend".
Abb. 15-4: Die Klassen Noten (UML-Klassendiagramm)
Beispiel: Array von int-Werten

Ein Array ist ein Objekt, das eine festgelegte Anzahl von Werten eines ausgewählten Typs aufnehmen kann.

Die Positionen der in einem Array enthaltenen Elemente sind durchnummeriert. Die jeweilige Positionsnummer wird als Index bezeichnet und besitzt den Typ int. Das Element an der ersten Position erhält stets den Index 0, das an der zweiten den Index 1 usw. Den Index des Elements an der letzten Position erhält man, indem man von der Größe des Arrays 1 abzieht.

img/Abb_15_5_Statisches_Array.svg
Abb. 15-5: Das Array notenKlArb besteht aus 4 Elementen vom Typ int.
  • Deklaration eines Arrays

    Bei der Deklaration des Arrays wird festgelegt, welchen Typ von Werten das Array aufnehmen kann.

    Dazu wird dem Array ein besonderer Typ zugewiesen. Dieser besteht aus aus dem Typ der Werte, die es später aufnehmen soll, gefolgt von einem Paar eckiger Klammern []. So besitzt zum Beispiel ein Array, das int-Werte aufnehmen kann, den Typ int[].

    JAVA
    int[] notenKlArb;
    Abb. 15-6: Deklaration eines Arrays, das int-Werte aufnehmen kann.
  • Erzeugung eines Arrays

    In Java ist ein Array ein Objekt. Dementsprechend kann es mit Hilfe des new-Operators erzeugt werden. Diesem folgt der Typ des Arrays, wobei zwischen den eckigen Klammern ein int-Wert eingefügt wird, der festgelegt, wie viele Werte das Array aufnehmen kann.

    Einmal festgelegt ist die Größe eines Arrays unveränderlich.

    Jedes Element eines Arrays wird mit dem Standardwert des jeweiligen Typs initialisiert. Die Elemente eines Arrays, das int-Werte aufnehmen kann, werden zum Beispiel mit 0 initialisiert.

    JAVA
    notenKlArb = new int[4];
    Abb. 15-7: Erzeugung eines Arrays, das vier int-Werte aufnehmen kann.
  • Zugriff auf die Elemente eines Arrays

    Der Zugriff auf ein Element eines Arrays erfolgt mit Hilfe seines jeweilgen Indexes. Dazu wird an den Objektnamen des Arrays ein Paar eckige Klammern angehängt und zwischen den Klammern der Index des gewünschten Elements angegeben.

    JAVA
    notenKlArb[0] = 13;
    notenKlArb[1] = 10;
    notenKlArb[2] = 11;
    notenKlArb[3] = 8;
    Abb. 15-8: Den Elementen eines Arrays einen Wert zuweisen.
  • Ermittlung der Größe eines Arrays

    Mit Hilfe des öffentlichen Attributs length lässt sich die Größe eines Arrays ermitteln.

    JAVA
    System.out.println("Anzahl der Klassenarbeiten: " + notenKlArb.length +"\n");

    for(int i=0; i<notenKlArb.length; i++) {
        System.out.println("Note " + (i+1) + ". Klassenarbeit: " + notenKlArb[i]);
    }
    Abb. 15-9: Ausgabe aller im Array gespeicherten Werte auf der Konsole (Quellcode).
    Konsole
    Anzahl der Klassenarbeiten: 4

    Note 1. Klassenarbeit: 13
    Note 2. Klassenarbeit: 10
    Note 3. Klassenarbeit: 11
    Note 4. Klassenarbeit: 8
    Abb. 15-10: Ausgabe aller im Array gespeicherten Werte auf der Konsole (Konsole).
Aufgabe

Aufgabe 15-2: Schülerliste

Vervollständigen Sie den Quellcode der main-Methode der Klasse Test, indem Sie die in den Kommentaren a) bis f) beschriebenen Anweisungen einfügen. Kopieren Sie dazu den (unvollständigen) Quellcode der Klasse Test (vgl. Abb. 15-11) sowie den Quellcode der Klasse Schueler in ein neues Eclipse-Projekt.

Lösung

JAVA
public class Test {

    public static void main(String[] args) {
        Schueler s1 = new Schueler("Max", "Maier");
        Schueler s2 = new Schueler("Moritz", "Schmitt");
        
        //a) Ein Array namens schuelerliste erzeugen, das 35 Objekte der Klasse Schüler aufnehmen kann:
             // -> hier entsprechenden Quellcode einfügen ...Schueler[] schuelerliste = new Schueler[35];
        
        //b) Schueler s1 in die schuelerliste an Position 0 einfügen:
             // -> hier entsprechenden Quellcode einfügen ...schuelerliste[0] = s1;
        
        //c) Schueler s2 in die schuelerliste an Position 1 einfügen:
             // -> hier entsprechenden Quellcode einfügen ...schuelerliste[1] = s2;
        
        //d) Schueler an Position 0 der schuelerliste entfernen:
             // -> hier entsprechenden Quellcode einfügen ...schuelerliste[0] = null;

        //e) Vornamen des Schülers an Position 1 der schuelerliste auf der Konsole ausgeben:
             // -> hier entsprechenden Quellcode einfügen ...System.out.println(schuelerliste[1].getVorname());
        
        //f) Größe des Arrays schuelerliste auf der Konsole ausgeben:
             // -> hier entsprechenden Quellcode einfügen ...System.out.println(schuelerliste.length);

    }

}
Abb. 15-11: Klasse Test
Aufgabe

Aufgabe 15-3: Kurierdienst I

Die Frankenkurier GmbH bietet Kurierfahrten für Unternehmenskunden an. Ein Kunde erteilt dabei den Auftrag Post von einer bestimmten Adresse abzuholen und an eine Zieladresse zuzustellen. Frankenkurier erfasst den neuen Auftrag und weist diesen dem jeweiligen Kunden zu. Meldet der Kurier, dass er den Auftrag ausgeführt hat, wird der Auftrag als erledigt gekennzeichnet.

Eine gültige Adresse erfordert folgende Angaben: Straße, Hausnummer, Postleitzahl und Ort. Bei jedem Kunden sollen dessen Firma sowie alle bisher von ihm erteilten Aufträge ersichtlich sein. Ein Auftrag enthalte neben Auftraggeber, Abholadresse, Zieladresse die Information, ob der Auftrag bereits erledigt ist oder nicht.

Aufgaben
  1. Erstellen Sie ein UML-Klassendiagramms. Gehen Sie dabei zunächst davon aus, dass jeder Kunde bis zu dreißig Aufträge erteilen kann. Lösung
    Lösung
    img/Abb_15_12_UML_KurierdienstI.svg
    Abb. 15-12: Kurierdienst (UML-Klassendiagramm)
  2. Erstellen Sie den Quellcode der Klasse Kunde. Lösung
    Lösung
    JAVA
    public class Kunde {

        private Adresse anschrift;
        private String firma;
        private Auftrag[] auftraege = new Auftrag[30];

        public Adresse getAnschrift() {
            return anschrift;
        }

        public void setAnschrift(Adresse pAnschrift) {
            this.anschrift = pAnschrift;
        }

        public String getFirma() {
            return firma;
        }

        public void setFirma(String pFirma) {
            this.firma = pFirma;
        }

        public void addAuftrag(Auftrag pAuftrag) {
            for(int i=0; i<auftraege.length; i++) {
                if(auftraege[i] == null) {
                    auftraege[i] = pAuftrag;
                    break;
                }
            }
        }

        public void setAuftrag(int pIndex, Auftrag pAuftrag) {
            auftraege[pIndex] = pAuftrag;
        }

        public Auftrag getAuftrag(int pIndex) {
            return auftraege[pIndex];
        }
        
        public void removeAuftrag(int pIndex){
            auftraege[pIndex] = null;
        }
        
        public boolean removeAuftrag(Auftrag pAuftrag){
            boolean entfernt = false;
            
            for(int i=0; i<auftraege.length; i++) {
                if(auftraege[i] == pAuftrag) {
                    entfernt = true;
                    auftraege[i] = null;
                }
            }

            return entfernt;
        }

        public int ermittleAnzahlAuftraege() {
            int anzahl=0;

            for(int i=0; i<auftraege.length; i++) {
                if(auftraege[i]!=null) {
                    anzahl++;
                }
            }

            return anzahl;
        }
        
    }
    Abb. 15-13: Klasse Kunde (Quellcode)