Collections (Unbekannte) Liste Sortieren

Gossi

Bekanntes Mitglied
Schönen Guten Tag, hab mal wieder ne Frage:

Ich habe in der Datenbank 2 Tabellen, eine beinhaltet SQL-Statements und eine beinhaltet, ob bei den Statements noch Variablen gesetzt werden müssen.

In Java bekomme ich nun also das Ergebnis des in Tabelle 1 eingetragenen Statements, zur verdeutlichung nen kleines Beispiel:

Tabelle 1:
ID|STATEMENT
1|select * from test_tabelle where besitzer = :besitzer

Tabelle 2:
ID|VAR_NAME|DEFAULT_VALUE
1|Besitzer|Gossi

TEST_TABELLE
ID|BESITZER|ORT|HAUSNUMMER
1|Gossi|Bassum|1
2|Gossi|Syke|2
3|Gossi|Bassum|3
4|Belzebub|Syke|5
5|Gossi|Bassum|9
6|Gossi|Syke|121
7|Belzebub|Bassum|53
8|Gossi|Bassum|63
9|Gossi|Bassum|14

Ich bekomme also eine Liste mit folgenden Werten (Sofern Besitzer auf Gossi gesetzt wird):
ID|BESITZER|ORT|HAUSNUMMER
1|Gossi|Bassum|1
2|Gossi|Syke|2
3|Gossi|Bassum|3
5|Gossi|Bassum|9
6|Gossi|Syke|121
8|Gossi|Bassum|63
9|Gossi|Bassum|14

Jetzt möchte ich aber, dass nur einmal Gossi erscheint und nur einmal Bassum und Syke, also so:

ID|BESITZER|ORT|HAUSNUMMER
1|Gossi|Bassum|1
3|||3
5|||9
8|||63
9|||14
2||Syke|2
6|||121

Und an diesem Punkt hängt es leider, hier nochmal nen kleiner Teil Code:

Main-Klasse: Abrufen der Daten (ID gibt die ID des Statements an und varList ist eine Liste mit Variablen)
Java:
List<General> attrList = generalManager.getQuery(id, varList);

Das ganze würde für das oben genannte Beispiel so aussehen:
Java:
List<AnzeigeVar> varList = new ArrayList<AnzeigeVar>();
AnzeigeVar var = new AnzeigeVar("Gossi"); //Sind noch nen paar Attribute mehr, aber das sprengt den Rahmen ^^
List<General> attrList = generalManager.getQuery(1, varList);

Nun nochmal meine Frage:
Wie kann ich es erreichen, das er die Liste Sortiert und zusammenfass, da es ja mehrere Statements gibt die immer unterschiedliche Listen zurück geben, mit unterschiedlicher Spaltenanzahl und unterschiedlichen Werten :bahnhof:

EDITH:
Mehr Code:

General-Klasse
Java:
package de.narz.portalweb.anzeige.domain;

import java.util.List;

public class General {

    private List<GeneralValue> param;
    private List<String> spaltenNamen;

    public List<GeneralValue> getParam() {
        return param;
    }

    public void setParam(final List<GeneralValue> param) {
        this.param = param;
    }

    public List<String> getSpaltenNamen() {
        return spaltenNamen;
    }

    public void setSpaltenNamen(final List<String> spaltenNamen) {
        this.spaltenNamen = spaltenNamen;
    }

}

GeneralValue:
Java:
package de.narz.portalweb.anzeige.domain;

public class GeneralValue {

    private String name;
    private String value;

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(final String value) {
        this.value = value;
    }

}
 
Zuletzt bearbeitet von einem Moderator:
wie soll man anhand EINES Abfrage-Beispiels überlegen, was der Code in verschiedenen Fällen leisten muss?
gibt es die Vorgabe, dass die Spalten immer von links nach rechts sortiert werden?

in deinem Beispiel könnte man ja auf die Idee kommen, nach Hausnummer zu sortieren und für mehrere Straßen mit derselben Hausnummer diese Hausnummer statt der Sraße wegzulassen..

----

im Allgemeinen ist es nur Sortieren, Comparator wählt die Spalte,
und dann die Daten anschauen, bei gleichen Werten den hinterten streichen, bzw. vielleicht noch irgendwo merken falls später erneut zu sortieren ist, Alternative [c]boolean anzeigen= true/false[/c],
das ist was für eine Schleife, if/else, Temp-Variablen usw., gute alte Handarbeit, da kann man nicht viel sagen,
anfangen 😉
 
Wie bekomme ich es dabei hin, dass die Liste nach [c]general.getParam.getValue()[/c] Sortiert wird?

Meine Überlegung war es, für jeden Wert in Spalte 1 eine eigene Liste zu machen, für Splte 2 genauso usw.

also Sowas

ID|BENUTZER|ORT|HAUSNUMMER
1|Gossi|Bassum|1
3|Gossi|Bassum|3
5|Gossi|Bassum|9
8|Gossi|Bassum|14
9|Gossi|Bassum|63

ID|BENUTZER|ORT|HAUSNUMMER
2|Gossi|Syke|2
6|Gossi|Syke|121

ID|BENUTZER|ORT|HAUSNUMMER
7|Belzebub|Bassum|53

ID|BENUTZER|ORT|HAUSNUMMER
4|Belzebub|Syke|5

Aber darunter leided die Performance wahrscheinlich, oder?

zumal ich aus diesen Listen dann wieder eine gemeinsame machen müsste....

Und nicht zu vergessen müsste ich für jede weiter Spalte noch eine Liste erstellen ???:L
 
wenn die Daten erst aus der DB kommen, kannst sie danach 1000mal ins letzte Byte zersägen und neu zusammenbauen, das kosten praktisch keine zusätzliche Zeit, sowieso langsam

----

Sortierung ist ein Standard-Thema, General kann Comparable sein oder du verwendest einen separaten Comparator,
sofern du nicht zu kennen gibst dort irgendwas zu wissen und bisschen beschreibst inwiefern dann noch eine Frage offen ist,
sehe ich wenig zu sagen

Java Comparator Example | Java Tutorials and Examples
 
Also, ich hab jez nen Comparator geschrieben, der sieht so aus:

Java:
public class RowComparator implements Comparator {

	@Override
	public int compare(final Object gen1, final Object gen2) {

		General row1 = (General) gen1;
		General row2 = (General) gen2;

		if (row1.getParam().get(0) != null && row2.getParam().get(0) != null) {
			if (row1.getParam().get(0).getValue()
					.equals(row2.getParam().get(0).getValue())) {
				return 0;
			}
			int count = 0;
			for (char c : row1.getParam().get(0).getValue().toCharArray()) {
				if (c < row2.getParam().get(0).getValue().charAt(count)) {
					return -1;
				} else if (c > row2.getParam().get(0).getValue().charAt(count)) {
					return 1;
				}
				count++;
			}
		}
		return 0;
	}

}

Funktioniert alles bestens, aber wenn ich jetzt versuche ne Prüfung für die zweite Spalte hinzuzufügen, schmeißt er die erste Sortierung ja wieder auseinander :bahnhof:

Habs versucht mit ner for-Schleife die gleich alle Spalten prüft, aber das ging, wie geschrieben, in die Hose.....
 
nebenbei:
Zwischenvariablen sind erlaubt,
definiere doch [c]v1 = row1.getParam().get(0).getValue()[/c]
statt jedesmal so langen Code zu schreiben

String hat übrigens eine fertige compare-Methode

-----

und der Weg für mehrere Spalten lautet:
Java:
int c = compareValues(0); // 0 = Index, erste Spalte
if (c != 0) return c;
c = compareValues(1); 
if (c != 0) return c;
c = ..
usw., gerne mit Schleife und was immer hilft,
der Reihe nach vergleichen, aber nur weitermachen wenn bisher alles gleich war
 
Bei einfachen Sortierkriterien kann man den Code noch selbst implementieren. Bei kombinierten Sortierkriterien wird es (wie Du ja auch schon festgestellt hast) schnell hässlich. Gerade bei sowas hilft der CompareToBuilder von apache commons-lang (Lang - Home). Bei dem appended man die Kriterien in der Reihenfolge der Sortierrelevanz (z.B. erst nach Ort und dann nach Hausnummer sortieren). Das sieht dann ungefähr so aus:
[Java]
...
return new CompareToBuilder().append(first.getOrt(), second.getOrt).append(first.getHausnr(), second.getHausnr()).toComparison();
[/Java]
 
Ok, editieren is ja nu nich mehr, hab nu den Comparator fertig:

Java:
public class RowComparator implements Comparator {

	@Override
	public int compare(final Object gen1, final Object gen2) {

		General row1 = (General) gen1;
		General row2 = (General) gen2;

		if (row1.getParam().get(0) != null && row2.getParam().get(0) != null) {
			int paramNr = row1.getParam().size();
			if (paramNr == 1) {
				return new CompareToBuilder().append(
						row1.getParam().get(0).getValue(),
						row2.getParam().get(0).getValue()).toComparison();
			}
			if (paramNr == 2) {
				return new CompareToBuilder()
						.append(row1.getParam().get(0).getValue(),
								row2.getParam().get(0).getValue())
						.append(row1.getParam().get(1).getValue(),
								row2.getParam().get(1).getValue())
						.toComparison();
			}
			if (paramNr >= 3) {
				return new CompareToBuilder()
						.append(row1.getParam().get(0).getValue(),
								row2.getParam().get(0).getValue())
						.append(row1.getParam().get(1).getValue(),
								row2.getParam().get(1).getValue())
						.append(row1.getParam().get(2).getValue(),
								row2.getParam().get(2).getValue())
						.toComparison();

			}

		}
		return 0;
	}

}

Ja Slater, Zwischenvariablen sind erlaubt, ich weiß ^^

So, Sortierung funktioniert nun richtig, danke euch allen für die Hilfe.
 
Hallo Gossi,
eine kleine Verbesserung noch. Comparator ist generisch. Schreibe also:
[Java]
... implements Comparator<General>
[/Java]
Entsprechend wäre die Signatur der compare-Methode dann:
[Java]
@Override
public int compare(final General gen1, final General gen2) {
[/Java]
Das Casten in Zeile 6 und 7 kannst Du Dir dann sparen und die Methode wird typsicherer... hmm irgendwie hab ich grad ein DejaVu. Fehlt jetzt nur noch SlaterB mit seinem Hinweis 😀

Und noch ein Hinweis zu Deiner Implementierung mit der verschiedenen Parameteranzahl. Das kann man so machen und vordergründig funktionert das auch. Beachte aber, dass compare Kommutativ sein muss, sprich compare(x, y) muss das gleiche Ergebnis liefern wie compare(y, x). Das ist bei Dir nur gegeben, wenn die paramNr bei beiden gleich ist.

Edit://Obwohl, ich seh grad, wenn sie das nicht ist, fliegt sowieso eine IndexOutOfBoundsException. Also vergiss es für diesen Fall und behalte es nur im Hinterkopf.
 

Neue Themen


Zurück
Oben