Adressbuch

Javinner

Top Contributor
@scratchy1
Wenn du sehen willst, wie die Leute von Oracle es gelöst haben, dann empfehle ich dir den Blick auf die ArrayList (suche in deiner IDE nach ArrayList(java.util))
Die Probleme, die du jetzt hast, hatten viele vor dir auch. Da es bei dir an Grundlagen mangelt, tue dir selbst den Gefallen und schaue dir an, wie Leute, die was davon verstehen, die Probleme seiner Zeit für uns alle gelöst haben. Das befreit dich vom Lernen der Grundlagen in keinster Weise, sondern soll dich dabei unterstützen, das System zu verstehen. Ich hoffe, du merkst es selbst, dass das hier sehr zäh abläuft :)
 

mihe7

Top Contributor
Als nächstes werde ich versuchen, das Adressbuch zu testen. Ich mache:
Um das Adressbuch sinnvoll testen zu können, bekommt es eine Methode
print().
Wenn Du das Adressbuch sinnvoll testen willst, dann musst Du Dir vor allem geeignete Testfälle überlegen.

Zum Beispiel:
1. ein neues Adressbuch hat 0 Einträge.
2. wenn Du einen Eintrag hinzufügst, hat es um einen Eintrag mehr
3. wenn Du einen Eintrag hinzufügst, ist der Eintrag hinterher auch im Adressbuch enthalten
usw.

Beim Aufstellen der Testfälle wirst Du feststellen, dass Du Dinge im Code noch gar nicht (bewusst) berücksichtigt hast. Zum Beispiel: was passiert, wenn es den hinzuzufügenden Eintrag bereits gibt? Wann sind zwei Einträge überhaupt gleich?Was soll passieren, wenn der Eintrag null ist?

Der Spaß lässt sich dann auch per Code testen.
 

scratchy1

Bekanntes Mitglied
Hallo Leute,
Seit gestern hab ich noch einiges getan. @Javinner: ich wusste gar nicht, dass man nach schon gelösten Problemen suchen kann, das muss ich mir merken und versuchen.
@mihe7: Ok, aber bevor ich das mache, versuch ich das Adressbuch erstmal ordentlich zu machen, ich bin jetzt wie folgt weit:
Java:
void verdoppleKapazität() {
        Person[] newpersons;

        newpersons = new Person[persons.length + persons.length];
        for (int j = 1; j <= persons.length ;j++) {
            newpersons[j-1] = persons[j-1];
        }
        persons = newpersons;

    }
 

scratchy1

Bekanntes Mitglied
Hallo Leut, ok ich hab jetzt das Ganze ein bisschen verbessert und eine print()-Methode zum Testen mir ausgedacht(welche natürlich noch falsch bzw. unsinnig sein könnte, aber ich wollts ausprobieren)
Java:
public class ArrayAdressBook1 {
    private Person[] persons;

    private int nextFreeIndex;// personenschondrin

    ArrayAdressBook1(int initialCapacity) {

        if (initialCapacity < 1) {
            initialCapacity = 1;
        }
        this.persons = new Person[initialCapacity];

    }

    void addPerson(Person p) {
        if (nextFreeIndex >= persons.length) {
            increaseCapacity();
        }
        persons[nextFreeIndex] = p;
        nextFreeIndex = nextFreeIndex + 1;
    }

    private void increaseCapacity() {
        Person[] newpersons;

        newpersons = new Person[persons.length * 2];
        for (int j = 0; j < persons.length; j++) {
            newpersons[j] = persons[j];
        }
        persons = newpersons;

    }

    void print() {
        int capacity;
        capacity = persons.length - nextFreeIndex;
        System.out.println("Anzahl Einträge: " + nextFreeIndex);
        System.out.println("Eintragskapazität: " + capacity);
        for (int i = 0; i < persons.length; i = i + 1) {
            persons[i].print();
            System.out.println();
        }
    }
}
Hier nochmal die print()-Methode gesondert:
Java:
void print() {
        int capacity;
        capacity = persons.length - nextFreeIndex;
        System.out.println("Anzahl Einträge: " + nextFreeIndex);
        System.out.println("Eintragskapazität: " + capacity);
        for (int i = 0; i < persons.length; i = i + 1) {
            persons[i].print();
            System.out.println();
        }
    }
 

Javinner

Top Contributor
eine print()-Methode zum Testen
Ich gehe davon aus, dass du:
  1. den Inhalt des Arrays persons
  2. die Anzahl der Einträge
  3. die aktuelle Kapazität des Arrays
in der Konsole ausgeben willst.

Zu 1:
Wenn die Klasse Person die toString()-Methode passend für die Klasse implementiert, dann müsstest du nur noch durch das Array iterieren und den Inhalt ausgeben.
Java:
public class Person
{
    private final String firstname;
    private final String secondName;
    Person(String fName, String sName)
    {
          this.firstName = fName;
          this.secondName = sName;
    }

    public String getFirstName()
    {
        return this.firstName;
    }
  
    public String getSecondName()
    {
        return this.secondName;
    }

    public String toString()
    {
        return "Name: ".concat(getFirstName).concat(", ").concat(getSecondName());
    }
}

public class AddressBook
{
    private Person[] persons;
    ...
   
    public void print()
    {
        for(Person p : this.persons)
       {
            System.out.println(p); // Hier wird dann die toString()-Methode der Klasse Person aufgerufen
       }
    }
}

Zu 2:
Du hast ein Array, welches größer ist, als Personen drin. Also sind Stellen im Array, welche unbelegt sind, ergo musst du durch das Array iterieren und die besetzten Stellen zählen.

Zu 3:
Die Kapazität des Arrays ist dessen Länge. Bedenke dabei, dass ein Array bei Null anfängt

Also könnte die print()-Methode so aussehen..
Java:
public void print()
{
     int besetzteStellen = zaehleStellen();
     System.out.println(String.format(Locale.GERMAN,"Besetzte Stellen: %d, Kapazität: %d%n",besetzteStellen, this.persons.lenght));
     for(Person p : this.persons)
    {
         System.out.println(p); 
    }
}
 

scratchy1

Bekanntes Mitglied
Hallo Leute,
Danke für die Tipps. Ich hatte und habe immer noch ein paar Schwierigkeiten mit Eclipse, aber ich hab meinen Test etwas abgeändert, weil er nicht korrekt das tat, was ich wollte. Und ich geb auch mal die Klasse Person ein die ich geschrieben habe:

Also erst mal der Test, ich wollte einmal ausgeben, wieviele Einträge im Adressbuch sind und einmal, wie groß die aktuelle Kapazität ist:
Java:
 void print() {

        System.out.println("Anzahl Einträge: " + nextFreeIndex);
        System.out.println("Eintragskapazität: " + persons.length);
        for (int i = 0; i < persons.length; i = i + 1) {
            persons[i].print();
            
        }
    }
Ich denke mal, hier sind keine Lücken (falls doch, wird das mir im Moment noch zu kompliziert, aber ich hab noch ein weiteres Vorhaben/Idee, dass/die ich nachher noch offenbaren werde).
So und jetzt die Klasse Person:
Java:
public class Person {
    String name;
    int birthday; /* in der Form JJJJMMTT */

    Person(String name, int birthday) {
        this.name = name;
        this.birthday = birthday;
    }

    void print() {
        System.out.println("Name: " + this.name);
        System.out.println("Geburtsdatum: " + this.birthday);
    }

    boolean isBirthday(int date) {
        return birthday % 10000 == date % 10000;
        // Das Prozentzeichen ist der Modulo-Operator, welcher
        // den Rest einer ganzzahligen Division liefert.
    }
}
Ok ich hab gerad Probleme mit Eclipse, ich hab da vorher mal rumgespielt, und meine Konfiguration ist im Moment chaotisiert, ich werd vor dem Testen das in Ordnung bringen müssen, da hab ich jemand anderem heut eine mail rausgegeben, welches Problem ich da hab.
Ansonsten, folgendes hab ich jetzt vor:
Ich will eine Klasse AdressBookTest mit einer main-Methode schreiben. In dieser erzeuge ich ein ArrayAdressBook1 mit Anfangsgröße 3. Dann will ich einige Person-Objekte erzeugen und sie mit der Methode addPerson() ins Adressbuch legen. Um zu überprüfen, ob das Einfügen und das automatische Verdoppeln der Kapazität funktioniert, will ich an geeigneten Stellen die Methode print() des Adressbuchs aufrufen.
Ich hoff, ich hab den Mund nicht zu voll genommen oder werde mich übernommen haben. ;)
 

mihe7

Top Contributor
Ich denke mal, hier sind keine Lücken
Jein. Vom Prinzip her fügst Du immer nur hinten an, so dass das Adressbuch lückenlos gefüllt wird und ein Löschen hast Du noch nicht implementiert.

Aber: Du fängst null nicht ab, daher ist es möglich, mittels addPerson(null) Lücken einzufügen. Die führen dann dazu, dass Deine print-Methode erstens nicht die richtige Anzahl an Personen (null ist keine Person) ausgibt und zweitens bei der Ausgabe der Personendaten abschmiert.

Ich hoff, ich hab den Mund nicht zu voll genommen oder werde mich übernommen haben.
Das denke ich mal nicht. Deine Beschreibung hört sich sehr gut überlegt an und dürfte genau so umsetzbar sein.
 

scratchy1

Bekanntes Mitglied
Hi Leute, Hi mihe7,
Aber: Du fängst null nicht ab, daher ist es möglich, mittels addPerson(null) Lücken einzufügen. Die führen dann dazu, dass Deine print-Methode erstens nicht die richtige Anzahl an Personen (null ist keine Person) ausgibt und zweitens bei der Ausgabe der Personendaten abschmiert.
Ach ja wieder das Problem :(. Da muss ich mir noch was fürs Abfangen überlegen.(Da brauch ich aber noch ein bisschen, um die Übersicht im Moment nicht zu verlieren.
Aber vorerst noch mein Rohversuch:
Java:
public class AddressBookTest {

    public static void main(String[] args) {
        // erzeugen ein ArrayAddressBook mit Anfangsgröße 3.
        ArrayAddressBook1[] addressbook = new ArrayAddressBook1[3];
        Person[] persons = new Person[3];
        // Person-Objekte erzeugen.
        Person[0] = new Person("Silversurfer", 19831007);
        Person[1] = new Person("Geilo", 19831007);
        Person[2] = new Person("Hulk", 19831007);
        // Person-Objekte ins Adressbuch reinzwirbeln.
        for (int i = 0; i <= 2; i++) {
            addressbook.addPerson();
        }
        // an geeigneter Stelle schauen, ob Verdopplung funktioniert.
        if (addressbook.length >= 4) {
            for (int i = 0; i <= addressbook.length; i++) {

                addressbook[i].print();
            }
        }
    }

}
Ich hab ein paar Fehlermeldungen, aber da hängt vieles damit zusammen, wo in Eclipse ich die ganzen Versuche abspeicher.
 
Zuletzt bearbeitet:

mihe7

Top Contributor
Ich kommentiere mal im Code:
Java:
public class AddressBookTest {

    public static void main(String[] args) {
        // hier erzeugst Du ein Array, das 3 ArrayAddressBook1-Objekte
        // aufnehmen kann
        // ArrayAddressBook1[] addressbook = new ArrayAddressBook1[3];
        // du willst:
        ArrayAddressBook1 addressbook = new ArrayAddressBook1(3);

        Person[] persons = new Person[3];
        // hier verwendest Du den Klassennamen, um auf 
        // auf ein Array zuzugreifen. Das funktioniert nicht
        //Person[0] = new Person("Silversurfer", 19831007);
        //Person[1] = new Person("Geilo", 19831007);
        //Person[2] = new Person("Hulk", 19831007);
        // du willst:
        persons[0] = new Person("Silversurfer", 19831007);
        persons[1] = new Person("Geilo", 19831007);
        persons[2] = new Person("Hulk", 19831007);

        for (int i = 0; i <= 2; i++) {
            // hier fehlt die Person, die hinzugefügt werden soll
            // addressbook.addPerson();
            // du willst:
            addressbook.addPerson(persons[i]);
        }
        // hier arbeitest Du mit der Länge des Arrays addressbook
        // das funktioniert nicht, weil dieses Array gar nicht verändert
        // wird. Vielmehr wird ein Array innerhalb des Adressbuchs
        // geändert
        // if (addressbook.length >= 4) {
        // du willst hier eine Methode des Adressbuchs benutzen
        // und zwar diejenige, die die Anzahl an Personen liefert.
        // Diese musst Du ggf. noch schreiben. Ich benutze mal
        // size():
        if (addressbook.size() >= 4) {
           // hier iterierst Du über alle Adressbücher, die im
           // adressbook-Array gespeichert sind. Da Du nur ein
           // Adressbuch brauchst und hast, ist das falsch
           // for (int i = 0; i <= addressbook.length; i++) {
           //     addressbook[i].print();
           // }
           // du willst:
           addressbook.print();
        }
    }
}
 

scratchy1

Bekanntes Mitglied
Ich kommentiere mal im Code:
Java:
public class AddressBookTest {

    public static void main(String[] args) {
        // hier erzeugst Du ein Array, das 3 ArrayAddressBook1-Objekte
        // aufnehmen kann
        // ArrayAddressBook1[] addressbook = new ArrayAddressBook1[3];
        // du willst:
        ArrayAddressBook1 addressbook = new ArrayAddressBook1(3);

        Person[] persons = new Person[3];
        // hier verwendest Du den Klassennamen, um auf
        // auf ein Array zuzugreifen. Das funktioniert nicht
        //Person[0] = new Person("Silversurfer", 19831007);
        //Person[1] = new Person("Geilo", 19831007);
        //Person[2] = new Person("Hulk", 19831007);
        // du willst:
        persons[0] = new Person("Silversurfer", 19831007);
        persons[1] = new Person("Geilo", 19831007);
        persons[2] = new Person("Hulk", 19831007);

        for (int i = 0; i <= 2; i++) {
            // hier fehlt die Person, die hinzugefügt werden soll
            // addressbook.addPerson();
            // du willst:
            addressbook.addPerson(persons[i]);
        }
        // hier arbeitest Du mit der Länge des Arrays addressbook
        // das funktioniert nicht, weil dieses Array gar nicht verändert
        // wird. Vielmehr wird ein Array innerhalb des Adressbuchs
        // geändert
        // if (addressbook.length >= 4) {
        // du willst hier eine Methode des Adressbuchs benutzen
        // und zwar diejenige, die die Anzahl an Personen liefert.
        // Diese musst Du ggf. noch schreiben. Ich benutze mal
        // size():
        if (addressbook.size() >= 4) {
           // hier iterierst Du über alle Adressbücher, die im
           // adressbook-Array gespeichert sind. Da Du nur ein
           // Adressbuch brauchst und hast, ist das falsch
           // for (int i = 0; i <= addressbook.length; i++) {
           //     addressbook[i].print();
           // }
           // du willst:
           addressbook.print();
        }
    }
}
Ah vielen Dank mihe7, jetzt ist mir einiges klarer geworden.
1. ich erzeuge ein Adressbuch mit 3 Einträgen durch
Java:
ArrayAddressBook1 addressbook = new ArrayAddressBook1(3);
2. Man kann direkt die neu erzeugten Person-objekte ins persons Array reinschreiben.
3. Man muss dem Addressbuch schon sagen, welche Person-objekte er aufnehmen soll, das macht der nicht automatisch.
Ok, und bei size() würd ich gern irgendwie an das nextFreeIndex aus der Klasse ArrayAddressBook1 rankommen, wenn das geht.
 

mihe7

Top Contributor
1. ja, ein Adressbuch, das anfänglich eine Kapazität für 3 Einträge besitzt.
2. ja. Ein Array kannst Du Dir einfach wie ein langes Regal mit einer festen Anzahl an Fächern vorstellen, die beginnend mit 0 durchnummeriert sind. Die Anweisung persons[0] = x; legt x somit im Fach 0 des Regals "persons" ab.
3. ja, Du musst ganz allgemein immer die Parameter angeben, die die Methode erwartet

Ok, und bei size() würd ich gern irgendwie an das nextFreeIndex aus der Klasse ArrayAddressBook1 rankommen, wenn das geht.
Wenn Du weißt, dass adressbook vom Typ ArrayAddressBook1 ist und Dir den Aufruf adressbook.size() ansiehst, dann siehst Du sofort, dass die Methode size() in der Klasse ArrayAddressBook1 deklariert sein muss. Und die (EDIT: Methode) kann - ein lückenloses Adressbuch vorausgesetzt - einfach nextFreeIndex zurückgeben.
 

scratchy1

Bekanntes Mitglied
Hi mihe7 &co:
So jetzt hab ich was gemacht und versuch auch noch die NullPointerException zu handeln:
Vielleicht kann man das mit dem Abfangen der Ausnahme . Vielleicht ginge es ungefähr so?:
Java:
public class AddressBookTest {

    public static void main(String[] args) {
        // erzeugen ein ArrayAddressBook mit Anfangsgröße 3.
        ArrayAddressBook1 addressbook = new ArrayAddressBook1(3);

        // Person-Objekte erzeugen.Ich will auf das Array zugreifen
        // und Person-Objekte ins Adressbuch reinzwirbeln.
        try {
            addressbook.addPerson(new Person("Silversurfer", 19831007));
            addressbook.addPerson(new Person("Geilo", 19831007));
            addressbook.addPerson(new Person("Hulk", 19831007));
        } catch (NumberFormatException e) {
        }
        // an geeigneter Stelle schauen, ob Verdopplung funktioniert.
        if (addressbook.size() >= 4) {

            addressbook.print();

        }
    }
}
Vielleicht könnte ich einen Index definieren in der catch-Klausel.
Gruß Scratchy
 

mihe7

Top Contributor
Das Hinzufügen erzeugt (bislang) keine Exception, sondern fügt einfach null in das Array ein. Insofern bringt es nichts, wenn Du beim Aufruf der Methode versuchst, eine Exception abzufangen.

Alles, was Du tun musst, ist in der Methode addPerson auf null zu prüfen und entsprechend zu reagieren.
 

scratchy1

Bekanntes Mitglied
Hallo mihe7,
ok, ich überlege, wie das aussehen könnte, vielleicht:
Java:
void addPerson(Person p) {
        if (nextFreeIndex >= persons.length) {
            increaseCapacity();
        }
        persons[nextFreeIndex] = p;
        nextFreeIndex = nextFreeIndex + 1;
        if (p==null) {
            System.out.print("Null ist keine Person");
        }
}
 

mihe7

Top Contributor
Du musst die Prüfung schon machen, bevor Du die übergebene Person zum Adressbuch hinzufügst. Aktuell fügst Du hinzu und schaust hinterher nach: oh, das ist ja keine Person, das melde ich mal.

Wie Du auf null reagierst, ist eine andere Frage. Du kannst z. B. einfach nichts tun oder eine Exception werfen (damit will ich Dich jetzt nicht überfordern). Weil kurz vor Weihnachten ist:

Java:
void addPerson(Person p) {
    if (p != null) {
        persons[nextFreeIndex] = p;
        nextFreeIndex++;
    }
}
 

scratchy1

Bekanntes Mitglied
Hi mihe7, was bedeutet != ? Ist das sowie ==?
Also der gleiche Vergleichsoperator?
Und wenn ja , was macht die Methode wenn(p!=null) nicht gilt?
Ach, oder bedeutet != dass p eben nicht null ist, also die Negation?
 

scratchy1

Bekanntes Mitglied
Hallo mihe7,
Jein. Vom Prinzip her fügst Du immer nur hinten an, so dass das Adressbuch lückenlos gefüllt wird und ein Löschen hast Du noch nicht implementiert.

Aber: Du fängst null nicht ab, daher ist es möglich, mittels addPerson(null) Lücken einzufügen. Die führen dann dazu, dass Deine print-Methode erstens nicht die richtige Anzahl an Personen (null ist keine Person) ausgibt und zweitens bei der Ausgabe der Personendaten abschmiert.
Also ich wurde zwischendurch gefragt:
Wenn Sie das jetzt mal zu Ende umsetzen, werden Sie feststellen, dass in der Methode print() noch ein kleiner Fehler ist. Sie bekommen nämlich eine NullPointerException, und zwar z.B. wenn Sie nach dem Einfügen der zweiten oder vierten Person print() aufrufen. Wenn Sie hingegen nach der dritten Person print() aufrufen, gibt es keine NullPointerException. Bitte ausprobieren!

Eine NullPointerException bedeutet, dass Sie eine Methode auf der leeren Referenz aufrufen. Haben Sie eine Idee, warum sie in den o.g. Fällen auftritt (bei drei Personen aber nicht) und wie Sie das verhindern können?"

Ich weiss im Moment nicht, warum, er meinte:"Und das hat *nichts* damit zu tun, dass null statt einer Person eingefügt wird, sondern passiert bei der letzten Version im "normalen Betrieb".

Probieren Sie es doch einfach mal aus. Und dann denken Sie nach, an welchen Stellen sich wohl in welchen Situationen null befindet, ob Sie das überhaupt verhindern wollen und wenn nein, wie Sie trotzdem die NullPointerException verhindern (verhindern, nicht abfangen!)."
 

mihe7

Top Contributor
Ich weiß jetzt nicht, um welchen Code es geht aber es liest sich so, als würdest Du in AddressBook#print über das ganze persons-Array iterieren. Das musst Du natürlich auf die Zahl der Einträge begrenzen, also statt
Java:
for (int i = 0; i < persons.length; i++)
musst Du
Java:
for (int i = 0; i < nextFreeIndex; i++)
schreiben.
 
X

Xyz1

Gast
Und wie sieht jetzt alles zusammengefasst aus? Denn dann kann ichs verkomplettieren. :) Aus Deinen postings stellt sich noch keine Frage heraus. :(
 

scratchy1

Bekanntes Mitglied
Hallo Leute,
erstmal die Klasse ArrayAddressBook1:
Java:
public class ArrayAdressBook1 {
    private Person[] persons;

    private int nextFreeIndex;// personenschondrin

    ArrayAdressBook1(int initialCapacity) {

        if (initialCapacity < 1) {
            initialCapacity = 1;
        }
        this.persons = new Person[initialCapacity];

    }

    void addPerson(Person p) {
        if (nextFreeIndex >= persons.length) {
            increaseCapacity();
        }
        if (p!=null) {
        persons[nextFreeIndex] = p;
        nextFreeIndex = nextFreeIndex++;
      
          
        }
    }

    private void increaseCapacity() {
        Person[] newpersons;

        newpersons = new Person[persons.length * 2];
        for (int j = 0; j < persons.length; j++) {
            newpersons[j] = persons[j];
        }
        persons = newpersons;

    }

    void print() {

        System.out.println("Anzahl Einträge: " + nextFreeIndex);
        System.out.println("Eintragskapazität: " + persons.length);
        for (int i = 0; i < persons.length; i = i + 1) {
            persons[i].print();
          
        }
    }
}
Hier die Klasse AdressBookTest:
Java:
public class AddressBookTest {

    public static void main(String[] args) {
        // erzeugen ein ArrayAddressBook mit Anfangsgröße 3.
        ArrayAddressBook1 addressbook = new ArrayAddressBook1(3);

        // Person-Objekte erzeugen.Ich will auf das Array zugreifen
        // und Person-Objekte ins Adressbuch reinzwirbeln.
      
            addressbook.addPerson(new Person("Silversurfer", 19831007));
            addressbook.addPerson(new Person("Geilo", 19831007));
            addressbook.addPerson(new Person("Hulk", 19831007));
      
      
        // an geeigneter Stelle schauen, ob Verdopplung funktioniert.
      

            addressbook.print();

        }
    }
Und hier die Klasse Person:
Java:
public class Person {
    String name;
    int birthday; /* in der Form JJJJMMTT */

    Person(String name, int birthday) {
        this.name = name;
        this.birthday = birthday;
    }

    void print() {
        System.out.println("Name: " + this.name);
        System.out.println("Geburtsdatum: " + this.birthday);
    }

    boolean isBirthday(int date) {
        return birthday % 10000 == date % 10000;
        // Das Prozentzeichen ist der Modulo-Operator, welcher
        // den Rest einer ganzzahligen Division liefert.
    }
}
Mein Meister/Mentor fragte mich nun, warum eine NullPointerException nur nach dem Aufruf von print() nach der 2. oder 4. Person, aber nicht nach der 3. Person auftaucht. Aber im Moment kann ich nichts ausprobieren:
Eine Fehleranzeige habe ich in der Klasse ArrayAddressBook1 print() is undefined for the type Person(in der Zeile
Java:
 persons[i].print();
ganz unten) und eine weitere in der Klasse ArrayAddressBookTest: ArrayAddressBook1 cannot be resolved to a type (in Zeile
Java:
ArrayAddressBook1 addressbook = new ArrayAddressBook1(3); )

Also ich hab gedacht, dass die Fehlermeldungen mir verständlich wären, wenn ich ArrayAddressBook1, Person und ArrayAddressBookTest nicht im gleichen package wären, aber sie sind alle in einem defaultpackage, der wiederum in einem source-Ordner drin ist, der selbst im Projekt AddressBookTest gespeichert ist.
 

temi

Top Contributor
Mein Meister/Mentor fragte mich nun, warum eine NullPointerException nur nach dem Aufruf von print() nach der 2. oder 4. Person, aber nicht nach der 3. Person auftaucht.
Der Grund dafür steht im Beitrag #76.
Denk mal darüber nach, wie dein Array aussieht, wenn es eine Länge von drei hat und du zwei Personen eingefügt hast!
Welcher Wert ist dann an der letzten Stelle?
Was passiert, wenn du auf diesen Wert (in der print()-Methode) zugreifen willst?
Welcher Wert steht an dieser Stelle, nachdem du eine dritte Person angefügt hast?
Was passiert mit dem Array, wenn du eine vierte Person anfügst?
Welcher Wert steht dann an der fünften Stelle?
 

scratchy1

Bekanntes Mitglied
Hi temi,
Beim Einfügen von 2 Personen ist das Array mit persons[0] und persons[1] gefüllt, an der letzten Stelle steht dann noch kein Wert, oder?
Wenn ich nun in print() auf den letzten Wert zugreifen will,hmm dann geht das nicht, weil da keiner ist, aber könnte er dann nicht einfach d einfach persons[0] und persons[1] ausdrucken, also Silversurfer und Geilo?, vielleicht nicht. Wenn ich eine 3. Person anfüge ,habe ich eine Lücke an 3. Stelle, kann das sein?
Ach und das hiesse, dass die 3. Person auch nicht eingefügt werden könnte.
 
Zuletzt bearbeitet:

temi

Top Contributor
Beim Einfügen von 2 Personen ist das Array mit persons[0] und persons[1] gefüllt, an der letzten Stelle steht dann noch kein Wert, oder?
Wenn ich nun in print() auf den letzten Wert zugreifen will,
Dann hast du eine Null-Pointer-Exception
aber könnte er dann nicht einfach
Wer ist denn "er"?
Wenn ich eine 3. Person anfüge ,habe ich eine Lücke an 3. Stelle, kann das sein?
Nein. Die ersten angefügte Person ist an der ersten Stelle, die Zweite an der Zweiten und die Dritte...
 

scratchy1

Bekanntes Mitglied
Frohe Weihnachten mihe7 und alle anderen :)
Ach dann ist, wenn ich auf dem Adressbuch print() aufrufe und dort über alle Slots iteriere (also auch die nicht befüllten), dann steht in den "hinteren" ja u.U. noch die leere Referenz. Und das ist das Böse an der Sache.
 

scratchy1

Bekanntes Mitglied
Vielen Dank. Könnt Ihr mir auch empfehlen, wie ich einen Screenshot machen könnte in Eclipse, ich hab gesucht, aber in Eclipse selbst scheint es das nicht zu geben. Ich möchte das machen, um meinen Package-Explorer zu screenshoten und dann meinem Sensei schicken.
 

mihe7

Top Contributor
Unter Windows: Screenshot des aktuellen Fensters mit Alt+Print in die Zwischenablage kopieren. Danach das Bild irgendwo einfügen. Oder das "Snipping Tool" verwenden.
 

scratchy1

Bekanntes Mitglied
Vielen Dank, es hat geklappt. Ich überlege jetzt als nextes, wie ich eine Instanz der Subklasse Student der Klasse Person auch testen kann.
Java:
public class Student extends Person {
int matriculationNr;
int semester;
Student(String name, int birthday, int matriculationNr, int semester) {
super(name, birthday);
this.matriculationNr = matriculationNr;
this.semester = semester;
}
void print() {
super.print();
System.out.println("Matrikelnr: " + matriculationNr);
System.out.println("Semesterzahl: " + semester);
}
int getMatriculationNr() {
return matriculationNr;
}
}
 

scratchy1

Bekanntes Mitglied
Der Test sieht nun so aus
Java:
public class AddressBookTest {

    public static void main(String[] args) {
        // erzeugen ein ArrayAddressBook mit Anfangsgröße 4.
        ArrayAdressBook1 addressbook = new ArrayAdressBook1(4);

        // Person-Objekte erzeugen.
        //  Person-Objekte ins Adressbuch reinzwirbeln.

        addressbook.addPerson(new Person("Silversurfer", 19831007));
        addressbook.addPerson(new Person("Geilo", 19831007));
        addressbook.addPerson(new Person("Hulk", 19831007));
        addressbook.addPerson(new Student("Planck", 18580423, 3454545, 47));

        // an geeigneter Stelle schauen, ob Verdopplung funktioniert.

        addressbook.print();

    }
}
 

scratchy1

Bekanntes Mitglied
Wenn ich ursprünglich teste, erhalte ich
Anzahl Einträge: 0
Eintragskapazität: 3
Mit dem einen Studenten dazu
Anzahl Einträge: 0
Eintragskapazität: 4
 

mihe7

Top Contributor
Warum ist die Anzahl der Einträge 0? Der Grund liegt in der falschen Zeile: nextFreeIndex = nextFreeIndex++;

Was macht der Postinkrement-Operator "++"? Er erhöht zwar nextFreeIndex, liefert aber den Wert vor der Erhöhung zurück.

Anfangs gilt nextFreeIndex == 0. Wird die o.g. Zeile ausgeführt, wird zuerst die rechte Seite ausgewertet, d. h. nextFreeIndex++ erhöht nextFreeIndex um 1, gibt aber 0 zurück. Die 0 wird anschließend nextFreeIndex zugewiesen. Ergebnis: nextFreeIndex bleibt 0.

Entweder schreibst Du nur nextFreeIndex++; oder nextFreeIndex = nextFreeIndex + 1;. Es gibt weitere Schreibweisen, die zum richtigen Ergebnis führen, die sind in der Form aber eher ungewöhnlich, daher lasse ich sie hier mal weg.
 

scratchy1

Bekanntes Mitglied
Ah ja vielen Dank, ich frag mich immer wie man sowas so schnell merken kann ;) , super, jetzt kommt
Anzahl Einträge: 4
Eintragskapazität: 6
Name: Silversurfer
Geburtsdatum: 19831007
Name: Geilo
Geburtsdatum: 19831007
Name: Hulk
Geburtsdatum: 19831007
Name: Planck
Geburtsdatum: 18580423
Matrikelnr: 3454545
Semesterzahl: 47
 

temi

Top Contributor
@scratchy1: Offenbar verwendest du Eclipse als IDE. Du solltest dich unbedingt mal mit den dort vorhandenen Möglichkeiten einen Code zu debuggen auseinander setzen. Solche Fehler musst du durch systematisches Vorgehen und entsprechende Breakpoints auch selbst finden können.

Da ich Eclipse nicht verwende, kann dich leider keine Tipps geben, aber es findet sich hier im Forum bestimmt jemand, der das kann.
 

scratchy1

Bekanntes Mitglied
Hallo Leute,
Vielen Dank für Eure Hilfe, ich hab viel gelernt, das ich aber immer noch verarbeiten und merken muss.
Es ist eigentlich fertig, weil es funktioniert. Ein paar Sachen kann man in weniger Zeilen schreiben (das mache ich gerade). Es ist nicht einfach und ich bin Anfänger :) . Als nächstes werde ich mir ein objektorientiertes Modell für einen intelligenten Kühlschrank ausdenken, indem ich die Gegenstände seiner Welt angebe und die Methoden,
die der Kühlschrank und diese Gegenstände besitzen müssen, um zu kommunizieren und ihre Aufgaben zu erledigen.
Ich muss noch sehr viel üben. Im Moment habe ich 2 Bücher und das Internet und immer wenn ich was ausprobiere, will ich nicht in die Musterlösung schauen aus den Büchern. Da stehen oft auch sowieso nicht viele Kommentare, manchmal gar keine. Aber ich mach mir auch keinen Zeitdruck, ich mache alles Schritt für Schritt, und wenn ich mich abmühen muss oder irgendwo feststecke, dann bleib ich einfach solange dran wie es sein muss. Am Besten wäre natürlich, wenn ich zu jemanden (Firma/Meister/Lehrer/Ausbilder) persönlich gehen könnte, denn im direkten Dialog oder in der Gruppe , kommt man sehr oft viel schneller und besser ans Ziel.
 

scratchy1

Bekanntes Mitglied
Hallo Leute ich wollte die eine for-Schleife durch eine Methode ersetzen, die ich in
https://docs.oracle.com/javase/8/do...java.lang.Object-int-java.lang.Object-int-int

gefunden habe: Es geht um die Methode arraycopy(), die ich statt der for-Schleife in der Verdopplungsmethode einsetzen möchte.
Der Aufruf müsste klappen, ich weiss allerdings nicht, ob und wenn ja, was in die Methode gehört,
das müsste ich mir noch überlegen.
Java:
 private void increaseCapacity() {
        Person[] newpersons;

        newpersons = new Person[persons.length * 2];
        //for (int j = 0; j < persons.length; j++) {
            //newpersons[j] = persons[j];
        //}stattdessen nun:
        arraycopy(newpersons,0,persons,0,persons.length);
      
        persons = newpersons;

    }
    static void arraycopy(Object src, int srcPos, Object dest, int   destPos, int length) {
      
    }
 

mihe7

Top Contributor
Die Methode existiert doch bereits, warum willst Du sie nochmal schreiben?

Die Quelle ist persons, das Ziel ist newpersons, Quell- und Zielposition ist jeweils 0 und die Länge ist durch persons.length bestimmt. Also:
System.arraycopy(persons, 0, newpersons, 0, persons.length);
Das ist alles.
 

scratchy1

Bekanntes Mitglied
Vielen Dank, mihe7,
ich hatte zuvor
Java:
arraycopy(persons, 0, newpersons, 0, persons.length);
ausprobiert, ohne die Methode nochmal zu schreiben, denn intuitiv weiss ich, dass die Methode schon existierte.
Also dann interpretiere ich das so, dass man eine schon vorhandene Methode mit System.methode() aufrufen soll.
Gruß,
Scratchy
 

mihe7

Top Contributor
Also dann interpretiere ich das so, dass man eine schon vorhandene Methode mit System.methode() aufrufen soll.
Nein. Die Methode ist in Klasse System definiert (daher kommt das System) und als static deklariert. Letzteres bedeutet, dass man die Methode verwenden kann, ohne vorher ein Objekt erstellen zu müssen.

Wenn Du Dir https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html ansiehst, gibt es z. B. static double abs(double); daher kannst Du
double x = Math.abs(-5.0) schreiben.
 

Ähnliche Java Themen

Neue Themen


Oben