Wie lassen sich deutsche Datum-Strings vergleichen und wahlweise auf- oder absteigend sortieren?
In der main-Methode des Beispiels wird ein String-Array mit vier
beliebigen Daten zuerst unsortiert und dann sortiert ausgegeben.
Schließlich werden vier Mal je zwei Werte miteinander
verglichen.
Den Vergleich selbst führt die Klasse DateComparator
durch, die die Schnittstelle Comparator
implementiert.
Das Interface deklariert eine Methode compare(String arg0,
String arg1)
, die die beiden zu vergleichenden Objekte als
Parameter entgegen nimmt. In dieser Methode muss der Vergleich der
beiden Objekte so durchgeführt werden, dass bei aufsteigender
Sortierung im Falle eines größeren ersten Wertes ein
positiver und im Falle eines größeren zweiten Wertes ein
negativer int
-Wert zurück gegeben wird. Bei
Gleichheit wird 0 zurück gegeben. Durch das Umkehren des
Rückgabe-Vorzeichens kann somit auch das Ergebnis des
Vergleichs umgekehrt werden.
Das Problem beim Vergleich von deutschen Datumswerten wird durch
Umorganisieren der Datumsanteile gelöst. Hierzu werden die
Anteile für Tag, Monat und Jahr jedes Einzeldatums gesondert in
einem Array abgelegt. Die drei Elemente werden anschließend
dergestalt neu angeordnet, dass von links nach rechts, das Jahr, der
Monat und der Tag in einem String erscheinen. Die beiden zu
vergleichenden, umgestellten Datumsstrings werden schließlich
der Methode String.compareTo()
übergeben, die
einen lexikalischen Vergleich durchführt.
import java.util.Arrays;
import java.util.Comparator;
public class DatumsVergleich {
public static void main(String[] args) {
String[] daten = { "16.05.1703", "08.12.1925", "08.06.1925",
"12.02.1031" };
System.out.println("Vorher:");
for (String s : daten) {
System.out.println(s);
}
System.out.println("\nNachher:");
Arrays.sort(daten, new DateComparator(false));
for (String s : daten) {
System.out.println(s);
}
DateComparator dc = new DateComparator();
System.out.println("Vergleich von " + daten[0] + " und " + daten[1]
+ ": " + dc.compare(daten[0], daten[1]));
System.out.println("Vergleich von " + daten[1] + " und " + daten[2]
+ ": " + dc.compare(daten[1], daten[2]));
System.out.println("Vergleich von " + daten[2] + " und " + daten[3]
+ ": " + dc.compare(daten[2], daten[3]));
System.out.println("Vergleich von " + daten[3] + " und " + daten[0]
+ ": " + dc.compare(daten[3], daten[0]));
}
}
class DateComparator implements Comparator<String> {
boolean sortType = true;
public DateComparator(){
this(true);
}
public DateComparator(boolean sortType){
this.sortType = sortType;
}
public int compare(String arg0, String arg1) {
String[] date0 = arg0.split("\\.");
String[] date1 = arg1.split("\\.");
if (date0.length != date1.length)
throw new ClassCastException();
String compStr0 = date0[2] + date0[1] + date0[0];
String compStr1 = date1[2] + date1[1] + date1[0];
if(!sortType)
return compStr0.compareTo(compStr1) * -1;
return compStr0.compareTo(compStr1);
}
}
Um die Reihenfolge des Vergleichs wechseln zu können und somit
z.B. eine auf- und absteigende Sortierung zu ermöglichen,
deklariert die Klasse DateComparator
zu diesem Zweck
zwei Konstruktoren, von denen einer einen boolschen Wert beim Aufruf
übergeben bekommt. Er steuert den gewünschten
Vergleichsmodus: Bei Übergabe von true
und als
Standardwert wird ein aufsteigender Vergleich wie oben beschrieben
durchgeführt. Bei Übergabe von false
wird
absteigend verglichen. Der nicht parametrisierte Konstruktor ruft
ganz einfach den zweiten mit dem Standardwert true
auf.
Der
Vergleich von jeweils zwei Objekten wird in den letzten Zeilen der
main-Methode gezeigt.
Das Sortieren eines Datums-Arrays benutzt die gleiche Technik. Die
Java-Core-Klasse Arrays
stellt eine Reihe
überladener statischer Methoden zur Sortierung von Arrays
bereit, die laut Dokumentation intern einen modifizierten
Mergesort-Algorithmus verwenden. Die hier verwendete Variante der
Methode bekommt neben dem zu sortierenden Array einfach ein Objekt
des DateComparator
als zweiten Parameter
übergeben. Die Methode compare()
muss hierbei
nicht gesondert aufgerufen werden.
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.