Ich möchte in einer Liste Objekte speichern welche namentlich benannte reguläre Ausdrücke darstellen, d.h. die Klasse hat zwei String-Members name und regexp. Nun möchte ich verhindern dass Duplikate in der Liste vorkommen. Unter einem Duplikat verstehe ich in diesem Kontext: Gleicher name ODER gleiche regexp, da es ja keinen Sinn macht dasselbe Muster unter mehreren Namen oder verschiedene Muster mit gleichem Namen zu definieren.
Welche Collection würdet ihr in diesem Fall verwenden? Ich hab zunächst natürlich an ein Set gedacht, aber wie mach ich das mit dem Hashcode in diesem Fall? Die Gleichheit ist ja durch eine ODER Verknüpfung definiert.
Zur Zeit hab ich die Liste indirekt über eine ArrayList abgebildet wobei ich vor jedem add mit contains überprüfe ob das Element schon enthalten ist. Je nach Ergebnis gebe ich wie bei einem Set true oder false zurück. Funktioniert natürlich, aber vielleicht gibt's ja eine bessere Lösung.
Dann überschreib doch die equals / hashCode Methode um zu prüfen ob 2 Elemente gleich sind. Dann kannst du auch wunderbar ein Set verwenden.
Die meisten IDEs unterstützen dich bereits beim generieren solcher Methoden. Die müsstest du dann ggf. noch an deine Bedürfnisse (Gleichheit bei Namen oder Regex) anpassen.
Ja so sieht die Klasse aus, in der equals Methode liefere ich true zurück wenn entweder name oder regexp gleich sind. Aber wie müsste die hashcode Methode in diesem Fall aussehen?
ich hab jetzt den Namen als Eindeutigkeitskriterium herangezogen und das Problem mit einem LinkedHashSet umgesetzt.
Allerdings ist da eine Frage aufgetaucht:
Hier meine equals-Methode:
Java:
@Overridepublicboolean equals (Object obj){System.out.println("equals von Pattern");if(obj==this){returntrue;}if(obj instanceofPattern){Pattern p=(Pattern) obj;return name.equals(p.name);}returnfalse;}
Wenn ich nun nacheinander versuche Elemente hinzuzufügen dann wird meine equals-Methode scheinbar nur dann aufgerufen wenn das Element bereits existiert ("equals von Pattern" erscheint nur dann auf der Konsole wenn ich versuche bereits vorhandene Elemente nochmals zu adden. Warum ist das so?
Java:
System.out.println(mySet.add(newPattern("a","")));System.out.println(mySet.add(newPattern("b","")));System.out.println(mySet.add(newPattern("c","")));System.out.println(mySet.add(newPattern("c","")));-> nur hier wird "equals von Pattern" ausgegeben
Die doHashcode - Methode habe ich so überschrieben:
In den ersten Fällen ist immer der hashcode unterschiedlich, also wird das Objekt nicht noch zusätzlich mit equals verglichen. Beim letzten hinzufügen ist der hashcode gleich zu dem vorletztem Objekt, also wird noch mit equals verglichen.
Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.