Hallo lina und MrWurf,
Mit Hashing zu arbeiten ist sicher sinnvoll, spätestens dann, wenn es ein paar Objekte mehr sind. Wenn man equals und hashCode ordentlich implementiert hat, kann man auch einfach alle Objekte in ein HashSet schieben.
Zu Deiner (MrWurf) Anmerkung, dass Du ungern equals überschreibst: Natürlich muss man da aufpassen. Equals sollte man nur dann überschreiben, wenn die Objekte wirklich immer als gleich anzusehen sind. Das ist aber natürlich dann der Fall, wenn sie das selbe reale Objekt repräsentieren (wie in dem Fall eben die Bestellung). Man kann sich dann natürlich noch fragen, ob es überhaupt notwendig ist, dass es mehrere solche Objekte gibt. Es ist ja auch schon problematisch, die Objekte immer zu synchronisieren.
Equals so zu überschreiben, dass es auf sich ändernden Eigenschaften beruht, ist eigentlich immer etwas problematisch, weil plötzlich zwei Objekte gleich sein können, die es vorher nicht waren. Das führt natürlich mit entsprechenden Datenstrukturen zu problemen (z.B. Hashtabellen)
Dieser Sachverhalt ist mir bei den User-Objekten über den Weg gelaufen - aber gelöst habe ich ihn anders.
Genau in dem Fall ist ein Comparator sinnvoll. Comparable zu implementieren ergibt eigentlich nur für eine irgendwie universelle Ordnung sinn. (z.B. für Datumsobjekte).
Ein paar kleine Anmerkungen zu Deiner Comparator-implementierung:
- Ich nehme an, Du musst noch Java 1.4 verwenden? Mit 1.5 geht das nämlich wesentlich eleganter.
- Du verwendest die Konstanten ORDERBY_*. Üblicherweise werden da nur ints verwendet. Da kann man dann z.B. auch nen switch() verwenden, ist aber auch so ok.
- Wenn ein Objekt null ist oder von einem anderen Typ, ist es gleich zu jedem anderen Objekt. Ich würde weder auf null noch auf den Typ prüfen sondern einfach den vergleich machen. Die Spezifikation von Comparator lässt es meines Wissens explizit zu, dass NullPointerExceptions oder ClassCastExceptions geworfen werden, wenn kein sinnvoller Vergleich möglich ist. Man sollte die Exceptions in dem Fall natürlich dokumentieren.
So wird die Implementierung weniger umständlich und es gibt einen Fehler, wenn man mit dem Comparator etwas vergleicht, wozu er nicht gedacht ist.
Die Java 1.5 implementierung sähe so aus:
public class UserComparator implements Comparator<User> {
public enum OrderBy {NAME, NUMBER};
private final OrderBy orderBy;
public UserComparator(OrderBy orderBy) {
this.orderBy = orderBy;
}
public int compare(User u1, User u2) {
switch(orderBy) {
case NAME:
return u1.getName().compareTo(u2.getName());
case NUMBER:
return u1.getNumber().compareTo(u2.getNumber());
}
throw new Error("Implementation error.");
}
}
Grüße
Daniel