|
Letzte
Bearbeitung dieses Dokuments: |
Voraussetzungen für das Verständnis dieses Dokuments:Grundkenntnisse in
der Programmierung von Java (Klassen, Methoden,
Schleifen). |
Ungefährer Zeitbedarf zum Durcharbeiten dieses Dokuments:Arbeitszeit:
Für das Implementieren komplexerer Abfragen hängt der Arbeitsaufwand stark von der Aufgabe und der Routine ab. Eine Schätzung des Zeitaufwandes kann in diesen Fällen nicht gegeben werden. |
Dieses Dokument enthält Code-Muster für eine einfache Generelle Klasse mit einer Liste mit BO (BO_Set) und Erweiterungen, die entsprechend den jeweiligen Anforderungen zusätzlich implementiert werden können.
Vorbedingung
Einfacher
Muster-Code für ein BO_Set
Anleitung
zur Adaptierung
* Änderung
des Namens der Java-Packages der Anwendung
* Änderung
des Namens der Klasse
* Adaptieren
des Kommentars
* Methoden
copyFromapplication_entity_BO(..) und isDifferent(..) prüfen
* Bei
Version 'MobileClient': Codieren der Sortier-Methode(n)
Spezieller
Muster-Code
*
Sortieren der Liste (aufsteigend)
*
Sortieren der Liste (absteigend)
Weitere
Schritte und verwandte Dokumentation
Tutorial für die Programmierung eines Heavyweight-Clients (Fat-Client) durchgearbeitet.
Datenmodell fertig ausgearbeitet.
Welche
Platzhalter durch Bezeichnungen des eigentlichen Projektes zu
ersetzen sind finden Sie im Abschnitt
Anleitung
zur Adaptierung.
package
application_package
.bo;
/*
*
Package mit den Klassen für die Serialization eines Objekts
dieser Klasse.
* Serialization ist notwendig um ein BO vom
Java Application Server (JAS)
* zum Client zu übertragen.
*/
import
java.io.Serializable;
/*
*
Package mit der Basisklasse für ein BO-Set. */import
js_base.bo.JSBS_BO_Set;
/*
*
Package mit der BO-Klasse, dessen Objekte in der Liste dieser Klasse
enthalten sind. */import
application_package
.bo.
application_entity
_
BO;
/**
*
* @author
name[at]company
* @date
20xx-xx-xx
*
* @description
* Generelle
Klasse für eine Liste von Business-Objects
* der
Klasse application_entity
_BO.
* Für
eine Beschreibung des BO sehen Sie bitte im Kommentar
* der
Klasse application_entity
_BO
nach.
*
* @change-log
* when who why
* -----------------------------------------------------------------
*
*/public
class
application_entity
_BO_Set
extends
JSBS_BO_Set
implements
Serializable
{
/*
* METHODEN *//* ---------------------
* METHODE zum Kopieren der Liste mit den BO eines
anderen Objekts dieser Klasse
* in diese Klasse.
*/
public
void
copyFrom
application_entity
_BO_Set(
application_entity
_BO_Set
parm
application_entity
_BO_Set)
{
/*
* Größe des Vectors mit den BO (der in der
geerbten Basisklasse definiert ist) feststellen
* und
Index zum Durchsuchen definieren. */
int
locintVectorSize
= parm
application_entity
_BO_Set.
vecRecordSet
.size();
int
locintVectorIndex;
/*
* Vector
mit der Liste der BO in dieser Klasse leeren.
*/
this
.
vecRecordSet
.removeAllElements();
/*
* Mit
einer for-Schleife alle BO in der Liste des als Parameter übergebenen
Objekts durchgehen. */
for
(locintVectorIndex
= 0;
locintVectorIndex
< locintVectorSize;
locintVectorIndex++)
{/*
* Das
durch den Index gewählte BO aus der Liste durch eine lokale
Variable leichter
* 'greifbar' machen.
*/
application_entity
_BO
locstructBO =
(
application_entity
_BO)
parmapplication_entity
_BO_Set.
vecRecordSet
.elementAt(locintVectorIndex);
/*
* Neues
BO 'konstruieren' und die Methode der BO-Klasse zum Kopieren der
Variablen-Werte
* aufrufen.
*/
application_entity
_BO
locstructBO_New =
new
application_entity
_BO();
locstructBO_New.copyFromapplication_entity
_BO(locstructBO);
/*
* Das
'neue' BO in die Liste dieses Objekts einfügen.
*/
this
.
vecRecordSet
.addElement(locstructBO_New);
};/*
* Status-Code
und erklärenden Zusatz-Text in dieses Objekt übernehmen.
*/
this
.
StatusCode
=
parm
application_entity
_BO_Set.
StatusCode
;
this
.
StatusMsg
=
parm
application_entity
_BO_Set.
StatusMsg
;
}/* ---------------------
* METHODE zum Vergleichen der Werte der in der Liste
enthaltenen Business-Objects.
* Voraussetzung ist, dass die
Sortier-Reihenfolge innerhalb der Liste gleich ist.
* Die
Methode liefert 'true' zurück wenn mindestens die Werte einer
Variablen
* in einem BO der Liste verschieden sind.
*/
public
boolean
isDifferent(
application_entity
_BO_Set
parm
application_entity
_BO_Set)
{
/*
*
Wenn der Parameter 'null' ist dann 'true' (verschieden) zurück
liefern. */
if
(parm
application_entity
_BO_Set
==
null
)
return
true
;
/*
*
Anzahl der BO ('Länge') in den Listen der beiden BO-Set-Objekte
ermitteln. */
int
intThisVectorSize
=
this
.
vecRecordSet
.size();
int
intParmVectorSize
=
parm
application_entity
_BO_Set.
vecRecordSet
.size();
/*
*
Wenn die Anzahl der BOs in den Listen verschieden ist dann sind beide
Sets verschieden. */
if
(intThisVectorSize
!= intParmVectorSize)
return
true
;
/*
*
Variable für die beiden zu vergleichenden BO definieren.
*/
application_entity
_BO structThis
application_entity
_BO;
application_entity
_BO structParm
application_entity
_BO;
/*
*
In einer 'for'-Schleife jedes einzelne BO 'herausholen' und die
Methode des BO
*
zum Vergleichen aufrufen.
*/
for
(
int
intVectorIndex
= 0; intVectorIndex < intThisVectorSize; intVectorIndex++)
{
/* 'Herausholen'
der beiden BO und übertragen auf die dafür vorgesehenen
Variablen. */
structThisapplication_entity
_BO
= (
application_entity
_BO)
this
.
vecRecordSet
.elementAt(intVectorIndex);
structParmapplication_entity
_BO
= (
application_entity
_BO)
parmapplication_entity
_BO_Set.
vecRecordSet
.elementAt(intVectorIndex);
/*
*
Prüfung ob eines oder beide BO 'null' sind; dann ist ein
besonderer Vergleich notwendig. */
if
(structThis
application_entity
_BO
==
null
)
{
/*
*
Vergleich über die Methode der Klasse ist nicht möglich
(weil Objekt 'null' ist);
*
aber beide BO sind 'verschieden' wenn das zu vergleichende BO
nicht 'null' ist. */
if
(structParm
application_entity
_BO !=
null
)
return
true
;
}
else
{
/*
*
Methode des BO aufrufen; darin wird auch behandelt wenn das als
Parameter übergebene BO
* 'null' ist. Wenn die BO
verschieden sind dann diese Methode beenden. */
if
(structThis
application_entity
_BO.isDifferent(structParm
application_entity
_BO))
return
true
;
}
}/*
* Beide Sets sind identisch; 'false' als Zeichen für
'nicht verschieden' zurückliefern. */
return
false
;
}
}
Anleitung
zur Adaptierung
Am
leichtesten funktioniert die Anpassung des Muster-Codes an die
eigenen Erfordernisse durch Kopieren des Muster-Codes und Verwendung
von
Edit
> Find/Replace...
.
|
|
Für
'Platzhalter', die nur einmalig im Muster-Code vorkommen ist die
'Find'-Funktion ist hilfreich zum Finden der beschriebenen
'Platzhalter'.
Änderung
des Namens der Java-Packages der Anwendung
package
application_package
.bo;
/*
D
er
Name dieses Packages kommt in der ersten Zeile und beim
import
der
Klasse für das zugehörige BO im Muster-Code vor.
Änderung
des Namens der Klasse
/*
*
Package mit der BO-Klasse, dessen Objekte in der Liste dieser Klasse
enthalten sind. */import
application_package
.bo.
application_entity
_
BO
;
Dieser
Name muss mit dem Namen der Klasse übereinstimmen, der beim
Eröffnen der Klasse gewählt wurde.
Der
Name der Klasse kommt mehrmals im gesamten Code vor.
Deswegen
empfehle ich, mit 'Find/Replace' alle Platzhalter
application_entity
_BO
im
Muster-Code durch den gewählten Klassen-Namen zu ersetzen.
Adaptieren
des Kommentars
'Kein
Kommentar ist besser als ein falscher'
.
Aus
diesem Grund ist im Muster-Code auch keine Hintergrund-Information
über Entwurfs-Entscheidungen für das BO vorhanden.
Zur
Information über den Geschäftszweck wird auf den Kommentar
bei der zugehörigen Generellen Klasse für das BO verwiesen.
Methoden
copyFrom
application_entity
_BO_Set(...)
und
isDifferent
(...)
prüfen
Die
beiden Methoden enthalten einen universellen Code der für das
Kopieren bzw. Vergleichen der einzelnen BOs der Liste die zugehörigen
Methoden der Klasse für ein BO aufruft.
Das
Ersetzen des Platzhalters
application_entity
_BO
ist
bereits erfolgt wenn Sie das im Abschnitt
Änderung
des Namens der Klasse
beschriebenen
Verfahren durchgeführt haben.
Bei
Version 'MobileClient': Codieren der Sortier-Methode(n)
Wenn
für dieses Business-Object auch die Version 'MobileClient'
(Erfassen und Verwalten von Daten auf der lokalen Datenbank eines
'Client'-Gerätes mit späterer Synchronisation mit der
zentralen Datenbank des Servers) vorgesehen ist, muss nach dem
Synchronisieren der Daten die Liste mit den BO möglicherweise
neu sortiert werden.
Nach
welchen Variablen sortiert wird und in welcher Klasse (dieser
Generellen, Server-Seite, Client-Seite) die Sortierung erfolgt hängt
von den Anforderungen des Anwendungsprogramms ab und kann nicht
generell beantwortet werden.
Eine Implementierung in dieser
(allgemeinen) Klasse für das BO ist sinnvoll, wenn das Sortieren
auf der Client-Seite und auf der Server-Seite erforderlich ist.
Den
Muster-Algorithmus für das Sortieren finden Sie in den Abschnitt
Sortieren
der Liste (aufsteigend)
und
Sortieren
der Liste (absteigend)
.
Spezieller
Muster-Code
In
diesem Teil wird Muster-Code vorgestellt, der nicht in jeder
Server-seitigen Klasse mit einer Liste von BO vorkommen wird und
deswegen nicht in den Muster-Code der Klasse aufgenommen wurde.
Sortieren
der Liste (aufsteigend)
Unter
Umständen ist es notwendig, die BO in der Liste anders zu
sortieren als sie durch das SQL-Kommando von der Datenbank selektiert
wurden.
Als Alternative zum Erstellen eines weiteren
Datenbank-Zugriffs bietet sich an, die BO innerhalb der Liste
entsprechend den geänderten Anforderungen zu sortieren.
In
diesem Muster-Code werden die BO nach den gewünschten Variablen
aufsteigend sortiert.
/* ---------------------
* METHODE zum Sortieren der BO innerhalb der Liste.
*
Verwendet wird ein doppelter Bubble-Sort.
*/
public
void
sortBy
Variable1_Variable2_Variable3_Variable4
()
{
/*
Variable für die beiden zu vergleichenden (und eventuell zu
tauschenden) BOs aus
* der Liste.
*/
application_entity
_BO struct1
application_entity
_BO
;
application_entity
_BO struct2
application_entity
_BO
;
/* Variable
für den Index zum Adressieren der BO in der Liste.
*/
int
intIndex
= 0;
/*
* Variable
für die 'Grenzen', ausserhalb derer die 'kleinsten' und
'größten'
* BO der Liste schon sortiert sind.
*
Ein Vorteil des Bubble-Sort ist, dass mit dem ersten Durchlauf die
'größten' bzw.
* 'kleinsten' BO sicher an die
richtige
Stelle
wandern und nach dem Durchlauf n
* mindestens die n
'größten' bzw. 'kleinsten' BO an der richtigen Stelle
sind.
* Dadurch muss mit jedem weiteren Durchlauf nur mehr
eine geringere Anzahl der BO
* verglichen (und eventuell
getauscht) werden.
* Die beiden Variablen verbessern den
Algorithmus, weil sie nach einem Durchlauf
* erkennen
lassen, bis zu welchen Index-Werten die BOs noch verglichen werden
müssen.
*/
int
intLowestSortedIndicator
= 0;
int
intHighestSortedIndicator
=
vecRecordSet
.size()
- 1;
/*
* Weitere Variable die notwendig sind um eine planbare
Steuerung der for-Schleifen zu
* erreichen.
*/
int
intLowerAlreadySortedIndex
= intLowestSortedIndicator;
int
intUpperAlreadySortedIndex
= intHighestSortedIndicator;
/*
*
Für den Vergleich von Text wird ein Collator verwendet; dieser
sorgt auch für die
*
passende Reihenfolge von Umlauten. */
java.text.Collator
locCollator =
java.text.Collator.getInstance();
locCollator.setStrength(java.text.Collator.TERTIARY
);
/*
*
In der while-Schleife das Vergleichen der BO so lange ausführen
bis
* in den for-Schleifen kein Tausch mehr erfolgt ist.
*
Das wird daran erkannt, dass die Variablen mit den Indizes, wie weit
die Liste
*
schon sortiert ist, noch einen zu untersuchenden Bereich
anzeigen. */
while
(intLowestSortedIndicator
< intHighestSortedIndicator) {
/*
*
Zuerst wird die Liste mit den BO von 'unten' (niederster Index) nach
'oben'
*
durchlaufen. Dabei wandern die 'größeren' BO nach
'oben'. */
/*
*
Der Durchlauf in der for-Schleife endet bei jenem Index, ab dem
beim
*
Sortieren von 'unten' nach 'oben' kein Tausch der BO mehr erfolgt ist
- d.h.
*
alle BO darüber sind schon in der richtigen
Reihenfolge. */
intUpperAlreadySortedIndex
= intHighestSortedIndicator;
/*
*
Indikator, bei welchem Index der letzte Tausch von BO erfolgt ist auf
den
*
Wert des unteren Indikators setzen. Damit wird die while-Schleife
beendet
*
wenn in der folgenden for-Schleife kein Tausch mehr
erfolgt. */
intHighestSortedIndicator
=
intLowestSortedIndicator;
/*
*
Der Durchlauf in der for-Schleife wird bei jenem Index begonnen, ab
dem
beim
*
Sortieren von 'oben' nach 'unten' kein Tausch der BO mehr erfolgt ist
- d.h.
*
alle BO darunter sind schon in der richtigen Reihenfolge - und geht
bis
*
zu jenem Index, bei dem beim Durchlauf von 'unten' nach 'oben' kein
Tausch
*
mehr erfolgt ist.
*/
for
(intIndex
= intLowestSortedIndicator + 1;
intIndex <=
intUpperAlreadySortedIndex;
intIndex++)
{
/*
*
Die beiden zu vergleichenden BO aus der Liste 'holen'. */
struct1
application_entity
_BO
=
(application_entity
_BO
)
vecRecordSet
.elementAt(intIndex
- 1);
struct2
application_entity
_BO
=
(application_entity
_BO
)
vecRecordSet
.elementAt(intIndex);
/*
*
Der folgende Vergleich ist Ihren individuellen Anforderungen
anzupassen.
*
Der Muster-Code geht davon aus, dass Variablen der Klasse 'String'
verglichen werden
*
und benutzt den 'Collator'
-
bei
numerischen Werten vereinfacht sich der Vergleich. */
if
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
> 0)
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
> 0))
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_3
.trim(),
struct2
application_entity
_BO
.
Variable_3
.trim())
> 0))
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_3
.trim(),
struct2
application_entity
_BO
.
Variable_3
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_4
.trim(),
struct2
application_entity
_BO
.
Variable_4
.trim())
> 0))
)
{
/*
*
BO sind in falscher Reihenfolge und müssen vertauscht
werden. */
vecRecordSet
.setElementAt(
struct2
application_entity
_BO
,
intIndex - 1);
vecRecordSet
.setElementAt(
struct1
application_entity
_BO
,
intIndex);
/*
*
Indikator, wie weit die Liste sortiert ist, anpassen. */
intHighestSortedIndicator
= intIndex;
}
}
/*
*
Jetzt wird die Liste mit den BO von 'oben' (höchster Index) nach
'unten'
*
durchlaufen. Dabei wandern die 'kleineren' BO nach
'unten'. */
/*
*
Der Durchlauf in der for-Schleife endet bei jenem Index, ab dem
beim
*
Sortieren von 'oben' nach 'unten' kein Tausch der BO mehr erfolgt ist
- d.h.
*
alle BO darunter sind schon in der richtigen
Reihenfolge. */
intLowerAlreadySortedIndex
= intLowestSortedIndicator;
/*
*
Indikator, bei welchem Index der letzte Tausch von BO erfolgt ist auf
den
*
Wert des oberen Indikators setzen. Damit wird die while-Schleife
beendet
*
wenn in der folgenden for-Schleife kein Tausch mehr
erfolgt. */
intLowestSortedIndicator
=
intHighestSortedIndicator;
/*
*
Der Durchlauf in der for-Schleife wird bei jenem Index begonnen, ab
dem
beim
*
Sortieren von 'unten' nach 'oben' kein Tausch der BO mehr erfolgt ist
- d.h.
*
alle BO darüber sind schon in der richtigen Reihenfolge - und
geht bis
*
zu jenem Index, bei dem beim Durchlauf von 'oben' nach 'unten' kein
Tausch
*
mehr erfolgt ist.
*/
for
(intIndex
= intHighestSortedIndicator - 1;
intIndex >=
intLowerAlreadySortedIndex;
intIndex--)
{
/*
*
Die beiden zu vergleichenden BO aus der Liste 'holen'. */
struct1
application_entity
_BO
=
(application_entity
_BO
)
vecRecordSet
.elementAt(intIndex);
struct2
application_entity
_BO
=
(application_entity
_BO
)
vecRecordSet
.elementAt(intIndex
+ 1);
/*
*
Der folgende Vergleich ist gleich wie beim Sortieren von 'unten' nach
'oben'.
*
Es ist zeitsparend, den einmal codierten Vergleich hierher zu
kopieren. */
if
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
> 0)
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
> 0))
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_3
.trim(),
struct2
application_entity
_BO
.
Variable_3
.trim())
> 0))
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_3
.trim(),
struct2
application_entity
_BO
.
Variable_3
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_4
.trim(),
struct2
application_entity
_BO
.
Variable_4
.trim())
> 0))
)
{
/*
*
BO sind in falscher Reihenfolge und müssen vertauscht
werden. */
vecRecordSet
.setElementAt(
struct2
application_entity
_BO
,
intIndex);
vecRecordSet
.setElementAt(
struct1
application_entity
_BO
,
intIndex + 1);
/*
*
Indikator, wie weit die Liste sortiert ist, anpassen. */
intLowestSortedIndicator
= intIndex;
}
}
}
}
Üblicherweise
wird die Methode zum Sortieren in einer Methode zugehörigen
BOS-Set aufgerufen - und zwar bevor die Methode ordnungsgemäß
beendet wird.
Unter
bestimmten Voraussetzungen kann die Methode auch im zugehörigen
BOC-Set aufgerufen werden.
Das ist dann sinnvoll, wenn die
CPU-Zeit auf einem Server zu bezahlen ist und daher möglichst
viel Rechenleistung auf einem Client-Computer ausgeführt werden
soll.
Sortieren der
Liste (absteigend)
Der
Muster-Code für das Sortieren nach absteigenden Kriterien ist
gleich wie der unter
Sortieren
der Liste (aufsteigend)
vorgestellte
Muster-Code.
Einziger Unterschied sind die Vergleiche in den
beiden if
.
/* ---------------------
* METHODE zum Sortieren der BO innerhalb der Liste
nach 'absteigenden' Kriterien.
* Verwendet wird ein
doppelter Bubble-Sort.
*/
public
void
sortDescendingBy
Variable1_Variable2_Variable3_Variable4
()
{
/*
Variable für die beiden zu vergleichenden (und eventuell zu
tauschenden) BOs aus
* der Liste.
*/
application_entity
_BO struct1
application_entity
_BO
;
application_entity
_BO struct2
application_entity
_BO
;
/* Variable
für den Index zum Adressieren der BO in der Liste.
*/
int
intIndex
= 0;
/*
* Variable
für die 'Grenzen', ausserhalb derer die 'kleinsten' und
'größten'
* BO der Liste schon sortiert sind.
*
Ein Vorteil des Bubble-Sort ist, dass mit dem ersten Durchlauf die
'größten' bzw.
* 'kleinsten' BO sicher an die
richtige
Stelle
wandern und nach dem Durchlauf n
* mindestens die n
'größten' bzw. 'kleinsten' BO an der richtigen Stelle
sind.
* Dadurch muss mit jedem weiteren Durchlauf nur mehr
eine geringere Anzahl der BO
* verglichen (und eventuell
getauscht) werden.
* Die beiden Variablen verbessern den
Algorithmus, weil sie nach einem Durchlauf
* erkennen
lassen, bis zu welchen Index-Werten die BOs noch verglichen werden
müssen.
*/
int
intLowestSortedIndicator
= 0;
int
intHighestSortedIndicator
=
vecRecordSet
.size()
- 1;
/*
* Weitere Variable die notwendig sind um eine planbare
Steuerung der for-Schleifen zu
* erreichen.
*/
int
intLowerAlreadySortedIndex
= intLowestSortedIndicator;
int
intUpperAlreadySortedIndex
= intHighestSortedIndicator;
/*
*
Für den Vergleich von Text wird ein Collator verwendet; dieser
sorgt auch für die
*
passende Reihenfolge von Umlauten. */
java.text.Collator
locCollator =
java.text.Collator.getInstance();
locCollator.setStrength(java.text.Collator.TERTIARY
);
/*
*
In der while-Schleife das Vergleichen der BO so lange ausführen
bis
* in den for-Schleifen kein Tausch mehr erfolgt ist.
*
Das wird daran erkannt, dass die Variablen mit den Indizes, wie weit
die Liste
*
schon sortiert ist, noch einen zu untersuchenden Bereich
anzeigen. */
while
(intLowestSortedIndicator
< intHighestSortedIndicator) {
/*
*
Zuerst wird die Liste mit den BO von 'unten' (niederster Index) nach
'oben'
*
durchlaufen. Dabei wandern die 'größeren' BO nach
'oben'. */
/*
*
Der Durchlauf in der for-Schleife endet bei jenem Index, ab dem
beim
*
Sortieren von 'unten' nach 'oben' kein Tausch der BO mehr erfolgt ist
- d.h.
*
alle BO darüber sind schon in der richtigen
Reihenfolge. */
intUpperAlreadySortedIndex
= intHighestSortedIndicator;
/*
*
Indikator, bei welchem Index der letzte Tausch von BO erfolgt ist auf
den
*
Wert des unteren Indikators setzen. Damit wird die while-Schleife
beendet
*
wenn in der folgenden for-Schleife kein Tausch mehr
erfolgt. */
intHighestSortedIndicator
=
intLowestSortedIndicator;
/*
*
Der Durchlauf in der for-Schleife wird bei jenem Index begonnen, ab
dem
beim
*
Sortieren von 'oben' nach 'unten' kein Tausch der BO mehr erfolgt ist
- d.h.
*
alle BO darunter sind schon in der richtigen Reihenfolge - und geht
bis
*
zu jenem Index, bei dem beim Durchlauf von 'unten' nach 'oben' kein
Tausch
*
mehr erfolgt ist.
*/
for
(intIndex
= intLowestSortedIndicator + 1;
intIndex <=
intUpperAlreadySortedIndex;
intIndex++)
{
/*
*
Die beiden zu vergleichenden BO aus der Liste 'holen'. */
struct1
application_entity
_BO
=
(application_entity
_BO
)
vecRecordSet
.elementAt(intIndex
- 1);
struct2
application_entity
_BO
=
(application_entity
_BO
)
vecRecordSet
.elementAt(intIndex);
/*
*
Der folgende Vergleich ist Ihren individuellen Anforderungen
anzupassen.
*
Der Muster-Code geht davon aus, dass Variablen der Klasse 'String'
verglichen werden
*
und benutzt den 'Collator'
-
bei
numerischen Werten vereinfacht sich der Vergleich. */
if
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
< 0)
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
< 0))
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_3
.trim(),
struct2
application_entity
_BO
.
Variable_3
.trim())
< 0))
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_3
.trim(),
struct2
application_entity
_BO
.
Variable_3
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_4
.trim(),
struct2
application_entity
_BO
.
Variable_4
.trim())
< 0))
)
{
/*
*
BO sind in falscher Reihenfolge und müssen vertauscht
werden. */
vecRecordSet
.setElementAt(
struct2
application_entity
_BO
,
intIndex - 1);
vecRecordSet
.setElementAt(
struct1
application_entity
_BO
,
intIndex);
/*
*
Indikator, wie weit die Liste sortiert ist, anpassen. */
intHighestSortedIndicator
= intIndex;
}
}
/*
*
Jetzt wird die Liste mit den BO von 'oben' (höchster Index) nach
'unten'
*
durchlaufen. Dabei wandern die 'kleineren' BO nach
'unten'. */
/*
*
Der Durchlauf in der for-Schleife endet bei jenem Index, ab dem
beim
*
Sortieren von 'oben' nach 'unten' kein Tausch der BO mehr erfolgt ist
- d.h.
*
alle BO darunter sind schon in der richtigen
Reihenfolge. */
intLowerAlreadySortedIndex
= intLowestSortedIndicator;
/*
*
Indikator, bei welchem Index der letzte Tausch von BO erfolgt ist auf
den
*
Wert des oberen Indikators setzen. Damit wird die while-Schleife
beendet
*
wenn in der folgenden for-Schleife kein Tausch mehr
erfolgt. */
intLowestSortedIndicator
=
intHighestSortedIndicator;
/*
*
Der Durchlauf in der for-Schleife wird bei jenem Index begonnen, ab
dem
beim
*
Sortieren von 'unten' nach 'oben' kein Tausch der BO mehr erfolgt ist
- d.h.
*
alle BO darüber sind schon in der richtigen Reihenfolge - und
geht bis
*
zu jenem Index, bei dem beim Durchlauf von 'oben' nach 'unten' kein
Tausch
*
mehr erfolgt ist.
*/
for
(intIndex
= intHighestSortedIndicator - 1;
intIndex >=
intLowerAlreadySortedIndex;
intIndex--)
{
/*
*
Die beiden zu vergleichenden BO aus der Liste 'holen'. */
struct1
application_entity
_BO
=
(application_entity
_BO
)
vecRecordSet
.elementAt(intIndex);
struct2
application_entity
_BO
=
(application_entity
_BO
)
vecRecordSet
.elementAt(intIndex
+ 1);
/*
*
Der folgende Vergleich ist gleich wie beim Sortieren von 'unten' nach
'oben'.
*
Es ist zeitsparend, den einmal codierten Vergleich hierher zu
kopieren. */
if
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
< 0)
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
< 0))
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_3
.trim(),
struct2
application_entity
_BO
.
Variable_3
.trim())
< 0))
|
(
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_1
.trim(),
struct2
application_entity
_BO
.
Variable_1
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_2
.trim(),
struct2
application_entity
_BO
.
Variable_2
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_3
.trim(),
struct2
application_entity
_BO
.
Variable_3
.trim())
== 0)
&
(locCollator.compare(
struct1
application_entity
_BO
.
Variable_4
.trim(),
struct2
application_entity
_BO
.
Variable_4
.trim())
< 0))
)
{
/*
*
BO sind in falscher Reihenfolge und müssen vertauscht
werden. */
vecRecordSet
.setElementAt(
struct2
application_entity
_BO
,
intIndex);
vecRecordSet
.setElementAt(
struct1
application_entity
_BO
,
intIndex + 1);
/*
*
Indikator, wie weit die Liste sortiert ist, anpassen. */
intLowestSortedIndicator
= intIndex;
}
}
}
}
Üblicherweise
wird die Methode zum Sortieren in einer Methode zugehörigen
BOS-Set aufgerufen - und zwar bevor die Methode ordnungsgemäß
beendet wird.
Unter
bestimmten Voraussetzungen kann die Methode auch im zugehörigen
BOC-Set aufgerufen werden.
Das ist dann sinnvoll, wenn die
CPU-Zeit auf einem Server zu bezahlen ist und daher möglichst
viel Rechenleistung auf einem Client-Computer ausgeführt werden
soll.
Weitere Schritte und verwandte Dokumentation
Dokument |
Inhalt |
Schritt desTutorials für die Entwicklung von Heavyweight-Client Anwendungen in dem die Implementierung der Generellen BO-Set Klasse vorgestellt wird. |
|
Muster-Code für die BO-Klasse mit der Definition der Variablen des Business-Object. |