Methode contains

Mein Problemm ist folgende.

  1. wenn ich in der main Methode 2 Studenten mit verschiedene namen und gleiche matrikelnummer immnatrikulieren lasse, wird beide immatrikuliert, dabei habe ich in der Klasse Student equals methode überschrieben. Gleichheit wird auf matrikelnummer geprüft

  2. Ich habe Studenten auf der uni und ich möchte Exmatrikulieren

ausgabe ist Der student mit Matrikelnummer 9874521 existiert nicht

Wo liegt mein Fehler?

//Bitte beachtet meine Exceptions nicht. Das thema habe ich nicht ganz dzúrch

public class Student {

	private String vorname;
	private String nachname;
	private String matrikelnummer;

	public Student(String vorname, String nachname, String matrikelnummer)throws Exception{
		
		setVorname(vorname);
		setNachname(nachname);
		this.matrikelnummer = matrikelnummer.trim();
	}

	public String getMatrikelnummer() {

		String ziffern = this.matrikelnummer.substring(1);
		return ziffern;

	}

	public String getVorname() {
		return vorname;
	}

	public void setVorname(String vorname) throws Exception {
		this.vorname = vorname.trim();
	}

	public String getNachname() {
		return nachname;
	}

	public void setNachname(String nachname) throws Exception {
		this.nachname = nachname.trim();
	}

	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Student){
			Student stud = (Student)obj;
			if(getMatrikelnummer() == stud.getMatrikelnummer()){
				return true;
			}
			
			
		}
		return false;
	}
	
}

public class Universitaet {

	List<Student> studenten = new LinkedList<Student>();

	public void immatrikulieren(Student stud) throws Exception {
		if (stud == null) {
			throw new Exception("Student darf nicht null sein");
		}
		if (studenten.contains(stud)) {
			System.out.println(String.format(
					"Der Strudent mit matrikelnummer %s existiert bereits",
					stud.getMatrikelnummer()));

		} else {
			studenten.add(stud);
		}
	}

	public void exmatrikulieren(Student stud) throws Exception {
		if (stud == null) {
			throw new Exception("Student darf nicht null sein");
		}
		if (studenten.contains(stud)) {
			studenten.remove(stud);
			
		} else {
			System.out.println(String.format(
					"Der student mit Matrikelnummer %s existiert nicht",
					stud.getMatrikelnummer()));
		}
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < studenten.size(); i++) {
			builder.append(studenten.get(i).getVorname()).append(" ")
					.append(studenten.get(i).getNachname()).append(" ")
					.append(studenten.get(i).getMatrikelnummer()).append("
");
		}
		return builder.toString();
	}

}

lg anni

    String ziffern = this.matrikelnummer.substring(1);

substring(1)?

Moin,

in Deinem ersten Code in Zeile 41:

if(getMatrikelnummer() == stud.getMatrikelnummer()){

Strings vergleicht man mit „.equals()“ !!! :stuck_out_tongue_winking_eye:

Gruß
Klaus

EDIT:
oops, was ist denn hier beim Java-Code schief gelaufen ??? :confused:

In der Klasse Student in Zeile 41: if(getMatrikelnummer() == stud.getMatrikelnummer()){
Strings werden nicht mit dem Vergleichsoperator verglichen, da dieser bei Objekten auf die Identität prüft und nicht auf Gleichheit (wie man vermuten könnte). Bei Objekten immer die methode equals benutzen.
if(getMatrikelnummer().equals(stud.getMatrikelnummer())) {

Hallo, ich habe das einfach mal weitenteils übernommen und Kommentare hinzugefügt:

 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication1;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author ikwudls
 */
public class Uni {

    public static class Student {

        private static final Pattern MAT_PAT = Pattern.compile("^\\d{10,}$"); // oder non-static
        private String vorname;
        private String nachname;
        private String matrikelnummer;

        public Student(String vorname, String nachname, String matrikelnummer) {
            this.vorname = vorname;
            this.nachname = nachname;
            setMatrikelnummer(matrikelnummer);
        }

        public String getVorname() {
            return vorname;
        }

        public void setVorname(String vorname) {
            this.vorname = vorname;
        }

        public String getNachname() {
            return nachname;
        }

        public void setNachname(String nachname) {
            this.nachname = nachname;
        }

        public String getMatrikelnummer() {
            return matrikelnummer;
        }

        public final void setMatrikelnummer(String matrikelnummer) {
            if (!MAT_PAT.matcher(matrikelnummer).find()) {
                throw new IllegalArgumentException("wrong mat: " + matrikelnummer);
            }
            this.matrikelnummer = matrikelnummer;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 89 * hash + (this.matrikelnummer != null ? this.matrikelnummer.hashCode() : 0);
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Student other = (Student) obj;
            if ((this.matrikelnummer == null) ? (other.matrikelnummer != null) : !this.matrikelnummer.equals(other.matrikelnummer)) {
                return false;
            }
            return true;
        }

        @Override
        public String toString() {
            return "Student{" + "vorname=" + vorname + ", nachname=" + nachname + ", matrikelnummer=" + matrikelnummer + '}';
        }
    }
    List<Student> studenten = new ArrayList<Student>(4000);

    public void immatrikulieren(Student stud) throws Exception {
        if (stud == null) {
            throw new Exception("Student darf nicht null sein");
        }
        if (studenten.contains(stud)) {
            System.out.println(String.format(
                    "Der Strudent mit matrikelnummer %s existiert bereits",
                    stud.getMatrikelnummer()));

        } else {
            studenten.add(stud);
        }
    }

    public void exmatrikulieren(Student stud) throws Exception {
        if (stud == null) {
            throw new Exception("Student darf nicht null sein");
        }
        if (studenten.contains(stud)) {
            studenten.remove(stud);

        } else {
            System.out.println(String.format(
                    "Der student mit Matrikelnummer %s existiert nicht",
                    stud.getMatrikelnummer()));
        }
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        for (Student student : studenten) {
            builder.append(student);
            builder.append('
');
        }
        return builder.toString();
    }

    public static void main(String[] args) throws Exception { // Exception eher schlecht
        Uni u = new Uni();
        System.out.println(u);
        u.immatrikulieren(new Student("thom", "müller", "1234567890"));
        u.immatrikulieren(new Student("keine", "ahnung", "0123456789"));
        u.immatrikulieren(new Student("mir-fällt", "nix-ein", "2345678901"));
        System.out.println(u);
        u.immatrikulieren(new Student(null, null, "0123456789")); // nicht mit 'ner Exception Software/Anwendung/Programm beenden
    }
}```

Ein Pattern muss man z. B. nur einmal übersetzen.

Viele Grüße!

hashCode() sieht noch schön doof aus … so punkt vor strich und so …
und equals() … naja … lieber erst prüfen was alles nicht equal ist und überall return false anstatt einmal sauber alles prüfen … und nur einmal jeweils return true / false … weis net was clean code zu sagt … die ursprüngliche variante von TO lässt sich aber einfacher verstehen

[QUOTE=Unregistriert]hashCode() sieht noch schön doof aus … so punkt vor strich und so …
und equals() … naja … lieber erst prüfen was alles nicht equal ist und überall return false anstatt einmal sauber alles prüfen … und nur einmal jeweils return true / false … weis net was clean code zu sagt … die ursprüngliche variante von TO lässt sich aber einfacher verstehen[/QUOTE]

…und Du bist hier nicht angemeldet. Sende Deine Beschwerde doch an NetBeans, vielleicht hören die auf Dich (nicht.)

Bleib bitte sachlich und vergraul hier nicht unsere Gäste.

(… … entfernt)

Hm, ja, ich bin hier sehr unsachlich und sollte mich zurückhalten…

substring habe ich gemacht, damit String ab 2. Zeichen kopiert wird und eine neue String bekomme. Erste Zeichen war bezeichnung für die uni

in der erste Code 41.Zeile war das Problem
Danke euch :slight_smile:

bin ich richtig daran?

contains ruft die equals methode auch. Equals methode ist in der Klasse Object schon definiert, aber man muss meistens überschreiben, wenn man die benutzen will, weil in der subklasse definierte methode lediglich die adressen der Objekte vergleicht?

lg anni

für eigene Klassen gilt das in der Regel,
für API-Klassen wie String offensichtlich schon vorhanden, sonst könnte man auch nichts dran ändern

[QUOTE=SlaterB]für eigene Klassen gilt das in der Regel,
für API-Klassen wie String offensichtlich schon vorhanden, sonst könnte man auch nichts dran ändern[/QUOTE]

danke
endlich was richtig verstanden und kann ich wenigsten Thema abhacken

            if (matrikelnummer == null || !MAT_PAT.matcher(matrikelnummer).find()) {
                throw new IllegalArgumentException("wrong mat: " + matrikelnummer);
            }
            this.matrikelnummer = matrikelnummer;
        }

        @Override
        public int hashCode() {
            // matrikelnummer kann nicht null sein:
            return matrikelnummer.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            // this.matrikelnummer kann nicht null sein:
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Student other = (Student) obj;
            return this.matrikelnummer.equals(other.matrikelnummer);
        }```

oder

```        @Override
        public int hashCode() {
            // matrikelnummer kann nicht null sein
            // und enthält nur 0 - 9
            // und ist nicht negativ oder größer (2^31)-1 :
            return Integer.valueOf(matrikelnummer);
        }```

Evtl. noch den Pattern anpassen, wenn vorne z. B. keine 0 stehen darf, oder mit einer Schleife über matrikelnummer iterieren oder Integer.valueOf(matrikelnummer) verwenden.

von Hash Code habe ich wirklich keine Ahnung..

Viele Grüße!

Danke für die Erklärung. Das ist noch chinesisch für mich. komme sicherlich nach einpaar Monaten zu deinem Code

lg anni

[QUOTE=anni80]Danke für die Erklärung. Das ist noch chinesisch für mich. komme sicherlich nach einpaar Monaten zu deinem Code

lg anni[/QUOTE]

Es kommt darauf an, welche Vorgaben ihr für die Matrikelnummer bekommen habt: keine 0 vorne, (und) nur aus dem Bereich xy bis za oder nur Primzahlen etc. pp. Ich kenne die Aufgabenstellung ja nicht.

hashCode() wird eigentlich „nur“ bei einer Set/Map benötigt. Eine (verkettete) Liste kann ja nur für jedes Element equals() aufrufen (über die Liste iterieren).

Es ist richtig, alle Klassen erben implizit von der Klasse Object, in Object ist equals() implementiert, aber nur so, dass auf ich nehme an referenzielle Gleichheit (Identität) überprüft wird.

http://www.google.de/search?q=java+equals+von+object

Ich hab’ das mal vollständig neu geschrieben und die Klasse Uni Thread-sicher gemacht (welche Interfaces man u. a. implementieren könnte, sind angegeben):

 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication1;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author ikwudls
 */
public class Uni /* implements Iterable<Uni.Student>, Serializable */ {

    public static class Student /* implements Comparable<Student>, Serializable, .... */ {

        /**
         * 1000 - 999999 (both inclusive)
         */
        private static final Pattern MAT_PAT = Pattern.compile("^[1-9]\\d{3,5}$");
        private String vorname;
        private String nachname;
        private String matrikelnummer;

        public Student(String vorname, String nachname, String matrikelnummer) {
            this.vorname = vorname;
            this.nachname = nachname;
            setMatrikelnummer(matrikelnummer);
        }

        public String getVorname() {
            return vorname;
        }

        public void setVorname(String vorname) {
            this.vorname = vorname;
        }

        public String getNachname() {
            return nachname;
        }

        public void setNachname(String nachname) {
            this.nachname = nachname;
        }

        public String getMatrikelnummer() {
            return matrikelnummer;
        }

        /**
         * 1000 - 999999 (both inclusive)
         *
         * @param matrikelnummer
         */
        public final void setMatrikelnummer(String matrikelnummer) {
            if (matrikelnummer == null || !MAT_PAT.matcher(matrikelnummer).find()) {
                throw new IllegalArgumentException("wrong matrikelnummer: " + matrikelnummer);
            }
            try {
                Integer.valueOf(matrikelnummer);
            } catch (NumberFormatException nfe) {
                throw new IllegalArgumentException("wrong matrikelnummer: " + matrikelnummer);
            }
            this.matrikelnummer = matrikelnummer;
        }

        @Override
        public int hashCode() {
            return Integer.valueOf(matrikelnummer);
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Student other = (Student) obj;
            return this.matrikelnummer.equals(other.matrikelnummer);
        }

        @Override
        public String toString() {
            return "Student{" + "vorname=" + vorname + ", nachname=" + nachname + ", matrikelnummer=" + matrikelnummer + '}';
        }
    }
    private final List<Student> studenten = new ArrayList<Student>(4000);

    public void im(Student stud) {
        if (stud == null) {
            throw new IllegalArgumentException("stud ist null: " + stud);
        }
        synchronized (studenten) {
            if (studenten.contains(stud)) {
                for (Student student : studenten) {
                    if (stud.equals(student)) {
                        throw new IllegalArgumentException(stud + " bereits vorhanden: " + student);
                    }
                }
            }
            studenten.add(stud);
        }
    }

    public void em(Student stud) {
        if (stud == null) {
            throw new IllegalArgumentException("stud ist null: " + stud);
        }
        synchronized (studenten) {
            if (!studenten.contains(stud)) {
                throw new IllegalArgumentException(stud + " nicht vorhanden");

            }
            studenten.remove(stud);
        }
    }

    @Override
    public String toString() {
        int i = 1;
        StringBuilder builder = new StringBuilder();
        synchronized (studenten) {
            for (Student student : studenten) {
                builder.append(String.format("% 7d: %s%n", i++, student));
            }
        }
        return builder.toString();
    }

    public static void main(String[] args) {
        Uni u = new Uni();
        System.out.println(u);

        u.im(new Student("Thom", "Müller", "1234"));
        u.im(new Student("keine", "Ahnung", "4321"));
        u.im(new Student("mir-fällt", "nix-ein", "1111"));
        System.out.println(u);

        try {
            u.im(new Student(null, null, "4321"));
        } catch (IllegalArgumentException iae) {
            System.out.println(iae);
        }
        u.em(new Student(null, null, "4321"));
        System.out.println(u);

    }
}```

Aber jetzt soll mit der Liste studenten ja auch etwas gemacht werden, deshalb dafür Methoden einfügen.

@Summer

ich drück es mal so aus

du definierst einen int mit einem wert : 5
und schreibst ne rechnung dazu : 89 * 5 + X
was wird jedes grundschulkind machen ? richtig : 89 * 5 auflösen , was auch mathematisch korrekt ist , dann X (falls komplexer term) und erst ganz zum schluss die addion
ich will mich hier nicht drüber streiten wie ichs dir versucht hab einfach klar zu machen , und kann deine reaktion auch nicht verstehen , aber einfach erstmal alles auf die IDE zu schieben anstatt mal selber das hirn anzuschalten dass das was die IDE da als default-template hat so ziemlicher käse ist … naja , man weis ja was drüben passiert ist

auch wurde ja bereits im anderen thread genannt : “hashCode() wird in der regel ein mal berechnet und dann gecachet”
gut : so ziemlich alles in der API hält sich nicht dran, aber wenn man selbst was schreibt könnte man mehrfaches neu-erzeugen, berechnen und wieder wegwerfen durch aus optimieren , sonst kann auch aus einer simplen hashCode() mal eben ein speicher-leak werden

und zu deiner anderen diskusion

Integer.parseInt() bzw Integer.valueOf() hat ja nun mal einen ganz anderen sinn als hashCode()
warum du also versuchst beide miteinander zu vergleichen wird zumindest mir nicht klar , vielleicht versuchst du ja es mir zu erläutern

[QUOTE=Unregistriert][/QUOTE]

Also zu deiner eigentlichen Frage müsste ich auf die Definition eines Hashwertes/codes eingehen, wovon ich aber, wie erwähnt, keine Ahnung habe.

Zu der anderen Frage: Es geht um den Wert eines primitiven (Variablen)-Typs und aus einer Berechnung x * y + z. klar, die kann man cachen (also: speichern), allerdings weiß ich nicht, ob das explizit den Flaschenhals vermeiden würde:

  return val;
}
return (val = x*y+z);```

Geschwindigkeitsvorteil, wenn doch immer "not equal to " ausgeführt werden muss?

Wegen dessen, was die IDE produziert, musst du dich, wie erwähnt, nicht bei mir beschweren; ich geb' aber zu, dass ich das ohne "scharfes Hinsehen" einfach so übernommen hab'.

sicherlich , ich hab ja auch erwähnt das ich nicht weis was z.b. “clean code” zu sagt (da ichs einfach immer noch nich gepackt hab mir das zu bestellen , vielleicht mal zu x-mas) , und ich gehe schon von aus das sich irgendwer bei dieser implementierung was gedacht haben wird , aber es ist schon irgendwie murks , und wirklich leserlich bzw leicht zu verstehen ist es auch nicht

gucken wir uns mal einige hash-algorithmen an : in der regel wird erst gepaddet und dann in einem loop blockweise miteinander verrechnet um eine feste ergebnislänge zu erhalten
man könnte nun z.b. alle member irgendwie bis auf ihre primitives runterbrechen (am einfachsten durch wiederum ähnlich implementierte hashCode() methoden) so das man diese in eine rechnung stecken kann

wenn man die regel : “gleicher inhalt erzeugt gleichen hashCode()” aufstellt so kann man für equals() angeben : wenn beide objekte nicht null sind , vom gleichen type sind und den gleichen hashCode() haben sind sie equals() , sonst nicht
was in code dann recht einfach mit einer prüfung auf NULL , auf instanceof und int==int umzusetzen ist

finde ich persönlich jetzt deutlich einfacher zu lesen und zu verstehen als das was netbeans da hingekleistert hat

aber naja , wir werden ziemlich OT
das grundproblem von TO war ja das er zwei objekte mit “==” statt equals() verglichen hat , womit seine eigene equals() nun mal fehlerhaft implementiert war