Java-Tutorials. Vor langer Zeit mal von mir angekündigt. Dann kam zu diesem Thema wieder nichts. Habe mir bisher einfach nicht die Zeit nehmen können, mir etwas zu überlegen, was gut in diese Rubrik passen könnte. Heute möchte ich aber zumindest mit einem sehr kleinen und recht simplen Beitrag beginnen, und wer weiß, vielleicht geht es danach ja sogar weiter. Je nachdem.
Kürzlich stand ich vor einem kleinen Problem, als ich in der Situation war, Daten über Lizenzen aus einem SAP-System auszulesen. Die Information lag in Form einer Tabelle als Vector<Vector<String>> vor. Aus diesem habe ich die benötigten Spalten in zwei String-Arrays rausgeschrieben: Lizenzkennzeichnung und das Gültigkeitsdatum. Diese Einträge sollten dann nach der Datums-Spalte sortiert werden. In diesem Augenblick fiel mir auf, dass ich keine spontane Idee hatte, wie ich zwei Arrays in Abhängigkeit voneinander sortieren sollte, also zwei Spalten gleichzeitig.
Eine Lösung des Problems ist mir dann aber nach kurzem Grübeln eingefallen: Eine passende Datenstruktur musste her, die ihre eigenen Sortierkriterien mitbringt:
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
; html-script: false ]class LicenseEntry { private static final String DELIMITER_CHARACTER = ":"; private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); String identifier; GregorianCalendar expirationDate; public LicenseEntry(String identifierString, String expirationDateString){ this.identifier = identifierString; this.expirationDate = (GregorianCalendar) stringAsCalendar(expirationDateString); } static Comparator<LicenseEntry> licenseComparator = new Comparator<LicenseEntry>(){ @Override public int compare(LicenseEntry license1, LicenseEntry license2) { return license2.expirationDate.compareTo(license1.expirationDate); } }; public Calendar stringAsCalendar(String dateString){ GregorianCalendar resultCalendar = new GregorianCalendar(); try { resultCalendar.setTime(dateFormat.parse(dateString)); } catch (ParseException parseException){ return new GregorianCalendar(); } return resultCalendar; } public String calendarAsString(Calendar calendar){ return dateFormat.format(calendar.getTime()); } @Override public String toString(){ return this.identifier + DELIMITER_CHARACTER + calendarAsString(this.expirationDate) + "\n"; } } |
Anschließend wollte ich einfach ein Array dieser Datenstruktur erzeugen und auf diesem toString() aufrufen, damit dann rekursiv alle toString()-Methoden seiner Elemente aufgerufen werden. Ach wie doof. So funktioniert das ja gar nicht. Kurzerhand habe ich mir also etwas ausgedacht, das toString() überschreibt, wie ich das gerne hätte:
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 |
; html-script: false ]final int resultTableSize = resultTable.size(); String licenseEntryArrayString = new Object(){ LicenseEntry[] licenses = new LicenseEntry[resultTableSize]; { int licenseIndex = 0; for(Vector<String> currentRow : resultTable){ licenses[licenseIndex] = new LicenseEntry(currentRow.get(LICENSE_IDENTIFIER_COLUMN), currentRow.get(LICENSE_EXPIRATIONDATE_COLUMN)); licenseIndex++; } Arrays.sort(licenses, LicenseEntry.licenseComparator); } @Override public String toString(){ String resultString = ""; for(LicenseEntry currentLicenseEntry : licenses){ resultString += currentLicenseEntry.toString(); } return resultString; } }.toString(); |
Ich bin mir zwar relativ sicher, dass hier einige Java-Profis und Design-Pattern-Götter die Hände über dem Kopf zusammenschlagen werden, aber ich glaube ganz so unbrauchbar ist das eigentlich nicht. Und fragt mich schon gar nicht wieso ich da eine anonyme Klasse genommen habe. Vielleicht war ich einfach in der Stimmung dafür. Ich hoffe der Code ist selbsterklärend genug. Das meiste ist sowieso zu speziell, wichtig ist allein die Struktur.