Es ist mir bisher zwar erst zwei Mal untergekommen, aber das ist mir diesen Eintrag Wert.
Listen in Java zu sortieren ist dank vieler Vergleichsmethoden relativ problemlos möglich. Aber es soll auch vorkommen (wie bei mir jetzt das zweite Mal), dass man in der Liste nach mehr als einem Kriterium sortieren möchte. Hier kommt der MultiComparator zum Einsatz.
Den unrsprünglichen MultiComparator habe ich bei AllExperts.com gefunden. Diesen habe ich mal auf die neue Generics-Welt in Java umgeschrieben.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| package what.ever.you.like;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* Comparator, der für das gegebene Objekt <code>T</code> mehrere Comperatoren
* für eine Mehrfachsortierung anwenden kann.
* @param <T>
*/
public class MultiComparator<T> implements Comparator {
List<Comparator<T>> comparators = new ArrayList<Comparator<T>>();
public void addComparator(Comparator comp) {
comparators.add(comp);
}
public void removeComparator(Comparator comp) {
comparators.remove(comp);
}
public int compare(T obj1, T obj2) {
int result = 0;
for (Comparator comp : comparators) {
result = comp.compare(obj1, obj2);
if (result != 0)
break;
}
return result;
}
} |
Diesem MultiComparator kann man jetzt weitere Comparatoren für ein beliebiges Objekt T hinzufügen. Diese sorgen dann für die eigentliche Sortierung. Hier ein kurzes Beispiel:
1
2
3
4
5
| MultiComparator<SomeObject> multiComp = new MultiComparator<SomeObject>();
multiComp.add(new FirstOtherComparatorForSomeObject());
multiComp.add(new SecondOtherComparatorForSomeObject());
Collections.sort(listWithSomeObjects, multiComp); |
Jetzt kann man für jeglichen complexeren Vergleich einen eigenen Comparator schreiben und diesen dann an den MultiComparator in der Reihenfolge anhängen, in welcher sortiert werden soll.
Posted in IT & Development, Java
Das Problem mit Beispielen ist immer, daß es nur Beispiele sind und dadurch nicht alle Fälle abgedeckt werden, die im richtigen Einsatz nötig sind. In diesem Fall geht es darum, daß die Struts-Doku leider das Beispiel von Checkboxen gemeinsam mit Labels nicht im Repertoire hat.
Labels im Zusammenhang mit Checkboxen sind eine sehr hilfreiche Sache und tragen auch zur Usability bei.
Struts bietet mit html:multibox die Möglichkeit, Checkboxen zu gruppieren. Ein Aufruf aus dem JSP mit einem Iterator über eine gewisse Anzahl von Checkboxen sieht bspw. so aus:
1
2
3
4
5
6
7
8
| <logic:iterate id="currentField" name="fields">
<html:multibox
property="fields"
styleClass="checkbox">
<bean:write name="currentField" property="id" />
</html:multibox>
<bean:write name="currentField" property="name" /><br />
</logic:iterate> |
In Jim’s Blog habe ich ein gutes Beispiel gefunden, wie hier Labels ohne größeren Aufwand verwendet werden können:
1
2
3
4
5
6
7
8
9
10
11
12
13
| <logic:iterate
id="currentField"
name="fields"
indexId=”count”>
<label for=”field.<bean:write name=’count’/>”>
<html:multibox
property=”fields”
styleClass=”checkbox”
styleId=’<%=”field.”+count%>’>
<bean:write name=”currentField” property=”id” />
</html:multibox>
<bean:write name=”currentField” property=”name” /><br />
</logic:iterate> |
Im Quelltext sieht das ganze dann so aus:
1
2
3
4
5
6
7
8
| <label for=”field.0″>
<input type=”checkbox”
name=”fields”
value=”1″
id=”field.0″
class=”checkbox” />
Ein Labelname<br />
</label> |
Und schon hat man wieder mehr Usability erreicht.
Posted in IT & Development, Java
Über die Criteria API von Hibernate lassen sich mittlerweile fast alle SQL-Queries wurderbar zusammenstellen. Nur hier und da gibt es ein paar Dinge, die schöner umgesetzt werden könnten.
Ich habe bspw. eine Criteria auf ein Entity welches wiederum verknüpfte Entities hat. Meine Sortierung möchte ich auf ein Property des verknüpften Entities legen. Von der Crietria API sind wir es eigentlich gewohnt, so vorzugehen:
1
2
| Criteria criteria = getCurrentSession().createCriteria(User.class);
criteria.addOrder(Order.asc("usergroup.name")); |
Leider funktioniert dieser Code nicht, die Exception ist, das das Property “usergroup.name” nicht bekannt ist.
Um das Problem zu umgehen, muss man der Criteria explizit angeben, dass man auf das Entity “UserGroup” zugreifen möchte. Folgendes funktioniert demnach:
1
2
3
4
| Criteria criteria = getCurrentSession().createCriteria(User.class);
Criteria subCrit = criteria.createCriteria(UserGroup.class);
// Sortierung auf UserGroup.name
subCrit.addOrder(Order.asc("name")); |
Dieser “Bug”, das eine solche Sortierung überhaupt noch nicht unterstützt wurde, gilt nur für die Version 2.1. Schade ist, dass weiterhin eine Subcriteria verwendet werden muss, um die Sortierung dann auf die darunterliegende Property ausführen zu können. Der Weg über die Punkt-Notation wäre wohl schöner und leichter.
Hoffentlich kommt das noch.
Posted in IT & Development, Java
Ich weiß gar nicht so genau, warum mir das erst jetzt aufgefallen ist … wahrscheinlich liegt es daran, dass ich foreach-Schleifen in PHP bisher immer nur zum Auslesen verwendet habe.
Die foreach-Schleife in PHP
1
2
3
| foreach ($myArray as $key => $value) {
// code here
} |
referenziert $value nicht, sondern kopiert die Werte. Das bedeutet, dass folgender Code keinen Effekt hat:
1
2
3
| foreach ($myArray as $key => $value) {
$value += "something";
} |
Nach dem Schleifendurchlauf sind die Werte des Arrays genau wie vorher.
Seit PHP 5 kann man dieses “Problem” folgendermaßen lösen:
1
2
3
| foreach ($myArray as $key => &$value) {
$value += “something”;
} |
Wie in der Doku (php.net) von PHP beschrieben, wird jetzt der Wert durch das &-Zeichen referenziert und nicht mehr kopiert.
Es wird noch darauf hingewiesen, dass man nach dem Schleifendurchlauf mit
die Referenz auflösen sollte, da diese auch nach der Schleife auf das letzte Element des Arrays zeigt.
Posted in IT & Development, PHP