1Danke
ERLEDIGT
JA
JA
ANTWORTEN
9
9
ZUGRIFFE
1525
1525
EMPFEHLEN
-
Hallo zusammen,
ich hoffe, ich bin hier im richtigen Unterforum für diese Art von Frage. Und zwar beschäftige ich mich seit relativ kurzer Zeit mit Java und bin gerade auf ein Problem mit Generics gestoßen. Es geht darum, eine bestehende ArrayList anhand von mir gewaehlter Kriterien zu sortieren. Dafür habe ich (grob betrachtet) folgenden Code verwendet. Dummerweise sagt er mir dann immer bei zuVergleichenderWertA > zuVergleichenderWertB , dass der Vergleichsoperator hierfür nicht definiert ist. Wenn ich stattdessen zuVergleichenderWertA.getGewicht() > zuVergleichenderWertB.getGewicht() verwende, funktioniert es. Da ich die compare-Methode aber gerne für verschiedene übergebene Attribute verwenden würde, gestaltet sich die Festlegung auf bestimmte Getter an dieser Stelle etwas ungünstig, da es nicht flexibel zu handhaben ist. Vor allem warum funktioniert der Vergleichsoperator == aber > dagegen nicht? Er müsste doch in beiden Fällen das gleiche Problem haben: Nämlich dass er nicht weiß, welche Attribute er überhaupt vergleichen soll. Daher wollte ich da irgendwie Platzhalter einbauen, aber es scheint nicht zu funktionieren... oder ist es gar nicht möglich, dass anders zu gestalten?
Ich habe schon zig Seiten im Internet besucht (unter anderem die JavaInsel), aber ich komme bei der OO-Gestaltung dieser Methode nicht vorwärts. Ich wäre euch sehr dankbar, wenn ihr ein paar (mehr) hilfreiche Tipps auf Lager habt, damit ich das Problem irgendwie lösen kann. Generics sind irgendwie nicht wirklich anfängertauglich, aber dummerweise scheine ich da nicht drum rum zu kommen. Vielen Dank schonmal für eure Antworten.
Mario
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
public class CollectionsTest implements Comparator<Test> { public void listeAnzeigen() { java.util.Collections.sort(liste, new CollectionsTest()); ... } @override public int compare(Test zuVergleichenderWertA, Test zuVergleichenderWertB) { int i = 0; if (zuVergleichenderWertA == zuVergleichenderWertB) { i = 0; } else if (zuVergleichenderWertA > zuVergleichenderWertB) { i = -1; } else { i = 1; } return i; } }
-
11.01.10 17:22 #2
Das ist normal, denn Objekte können nicht mit größer oder kleiner verglichen werden, das geht nur mit primitiven Datentypen, also int, short, long, double oder float (wenn ich nichts vergessen habe). Damit wäre Deine Implementierung immer bezogen auf die Attribute, d.h. Du vergleichst z.B. Strings mit compateTo() und primitive Datentypen mit ==, > oder < und gibst entsprechend das zurück, was Du für kleiner oder größer hälst.
CU schnuffie
Fragliche Fragen stellende Fragensteller sind für verantwortungslose Antworten antwortender verantwortlicher Antworter selbst verantwortlich.
-
Hallo, erstmal danke für deine schnelle Antwort. Ok, das mit den Objekten vergleichen ist mir nun klar. Es könnte ja theoretisch auch ein String an die Methode übergeben werden, so dass ein < oder > nicht funktionieren würde. Bei dem compareTo müsste ich doch dann aber auch mit nem Getter ein bestimmtes Attribut aus der Klasse Test ansprechen, damit ich das vergleichen kann oder? Wenn ich aber z.B. in der Klasse Test 10 verschiedene Attribute habe, wovon ich z.B. immer mal nach verschiedenen Attributen sortieren möchte, komme ich mit nem expliziten Getter auf ein bestimmtes Attribut nicht weiter, denn dann würden mir auch die übergebenen Parameter (ein bestimmtes Attribut zweier Objekte) nicht weiterhelfen. Wenn ich als z.B. nach Größe sortieren möchte, dann brauch ich den Getter für Größe, möchte ich aber wie in dem Beispiel-Code nach Gewicht sortieren, brauche ich den Getter für Gewicht. Ich weiß nicht, ob verständlich geworden ist, worauf ich hinaus will, aber das Problem lässt sich irgendwie schlecht beschreiben (besonderns wenn man keine Ahnung von Generics hat).
-
12.01.10 07:54 #4
Moin,
ich muss zugeben, dass sich mir Dein konkretes Problem nicht so ganz erschlossen hat.
Wenn Du in Deiner Klasse zehn verschiedene Attribute hast, brauchst Du auch entsprechend 10 Get- und Set-Methoden, um drauf zugreifen zu können.
Falls Du mit "Parameter" diejenigen meinst, die Du dem Konstruktor der Klasse mitgibst, brauchst Du entweder EINEN Konstruktor mit allen denkbaren Attributen oder halt mehrere spezifische Konstruktoren mit den jeweils gewünschen Attributen (gleiches gilt dann ggf. auch für 'normale' Methodenaufrufe) !
Vlt. würde ja mit einen Code-Beispiel deutlicher,m was Du meinst ....
Gruß
KlausEs ist noch kein Meister vom Himmel gefallen - sonst hätte man schon längst seine Leiche gefunden !!
Falls ich helfen konnte, wäre eine Bewertung oder ein Danke nett ;-)
-------------------------------------------------------------------------------------------------
Ich beantworte keine Fragen per PN !!
Stellt Eure Fragen im Forum - dann haben alle etwas davon !!
-
12.01.10 09:06 #5
Eigentlich klingt das für mich wie "Reflection". Du könntest bei jedem beliebigen Objekt z.B. alle Getter ermitteln und entsprechend aufrufen und vergleichen:
Code :1 2 3 4 5 6 7 8
for (Method m : irgendeinObject.getMethods()) { if (m.getName().startsWith("get")) { if (m.getReturnType().isPrimitive()) { [COLOR=seagreen]// prüfe mit "<" oder "==" oder ">"[/COLOR] } } [COLOR=seagreen]// u.s.w.[/COLOR] }CU schnuffie
Fragliche Fragen stellende Fragensteller sind für verantwortungslose Antworten antwortender verantwortlicher Antworter selbst verantwortlich.
-
Hallöchen ihr 2, danke für eure Bemühungen. Ich habe mir schon gedacht, dass das Problem eventuell nicht hinreichend von mir erklärt wurde, da es ein wenig schwer ist, etwas zu erklären, von dem man wenig Ahnung hat.
Schnuffies Antwort könnte wohl schon in die Richtung gehen, aber ich konnte es bisher noch nicht ausprobieren.
@VFL_freak
Das mit den Gettern und Settern für jedes Attribut ist mir bewusst. Das stellt auch kein Problem dar, da ich für die 10 Attribute die jeweiligen Getter und Setter schon erstellt habe. Ich versuche nochmal, das Problem näher zu veranschaulichen. Nehmen wir mal an, ich habe eine ArrayList mit den Objekten mit je 10 Attributen (z.B. Stärke, Gewicht, etc.) auf der Konsole ausgegeben und möchte die je nach Belieben nach einem anderen Attribut sortieren (collections.sort). Um jetzt z.B. nach Gewicht zu sortieren, habe ich mit dem folgenden Comparator gearbeitet:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
public class CollectionsTest implements Comparator<Test> { public void listeAnzeigen() { java.util.Collections.sort(liste, new CollectionsTest()); ... } @override public int compare(Test zuVergleichenderWertA, Test zuVergleichenderWertB) { int i = 0; if (zuVergleichenderWertA == zuVergleichenderWertB) { i = 0; } else if (zuVergleichenderWertA.getGewicht() > zuVergleichenderWertB.getGewicht()) { i = -1; } else { i = 1; } return i; } }
Collections.sort nimmt dann automatisch die Methode compare (die von mir ja nach meinen Vorgaben überschrieben wurde). Möchte ich jetzt aber z.B. nach Stärke sortieren, kann ich diese überschriebene Methode nicht verwenden, da ich dort ja explizit den Getter von Gewicht angegeben habe (zuVergleichenderWertA.getGewicht()). Für eine Sortierung nach Stärke müsste dann ja zuVergleichenderWertA.getStaerke() stehen. Für jedes Attribut steht dort also eine andere Programmzeile. Die Frage ist also, wie ich den Part mit den Gettern so gestalten kann, dass ich immer die gleiche compare Methode verwenden kann, egal nach welchen Attributen ich sortieren möchte. Es werden ja immer 2 Werte an die Methode übergeben (zuVergleichenderWertA und zuVergleichenderWertB). Es würde sich bei den zu vergleichenden Attributen auch immer um primitive Datentypen handeln. Nur der Part mit dem Getter müsste dynamisch sein. Ich hoffe, ich konnte das Problem jetzt etwas deutlicher darstellen. Eine bessere Umschreibung fällt mir leider dazu nicht ein...
-
12.01.10 13:47 #7
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Hi.
Es gibt eine zweite Collections.sort Methode wo du den zu verwendenden Comparator angeben kannst. Definiere für jedes deiner Attribute einen Comparator und rufe dann die sort Methode entsprechend auf.
GrußIf at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
Hallo deepthroat,
gelesen hab ich das mit dem wählbaren Comparator schon und ich bin auch der Meinung, dass ich oben beim Aufruf von Collections.sort eben diese Variante genutzt habe (java.util.Collections.sort(liste, new CollectionsTest());). Allerdings rufe ich dort ja sozusagen die Klasse CollectionsTest auf (die die compare Methode enthält). Ich kann mir allerdings im Moment nicht so richtig vorstellen, wie ich dort einen anderen Comparator (Namen) angeben kann (außer noch mehr Klassen erstellen, was aber wohl nicht so der beste Weg ist). Ich kann ja nicht mal den Namen der Methode compare ändern, da dieser Name so vorgeschrieben ist.
Hast du zufällig in ner groben Übersicht irgendwo nen Codeschnipsel rumliegen, der mir das Ganze veranschaulichen könnte?
-
12.01.10 14:54 #9
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Eben.
Warum? Den Code für die unterschiedlichen Vergleiche mußt du ohnehin schreiben.
GrußCode java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
class Foo { Comparator<Test> sortBy; class SortByName implements Comparator<Test> { @override public int compare(Test zuVergleichenderWertA, Test zuVergleichenderWertB) { ... } } class SortByWeight implements Comparator<Test> { @override public int compare(Test zuVergleichenderWertA, Test zuVergleichenderWertB) { ... } } ... sortBy = new SortByWeight(); // oder sortBy = new SortByName(); ... Collections.sort(xyz, sortBy);
PS: Wenn der Vergleich nicht "teuer" ist, kannst du übrigens die Funktion vereinfachen:
Code java:1 2 3 4
// nach Gewicht sortieren. public int compare(Test a, Test b) { return (a.getGewicht() - b.getGewicht()); }
Geändert von deepthroat (12.01.10 um 15:01 Uhr)
If at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
Danke für deine schnelle Antwort. Ich dachte mir, dass das mit den zig verschiedenen Klassen nur zum Vergleichen vielleicht nicht der eleganteste Weg ist. Aber da habe ich wohl falsch gedacht. Ich werde das einfach mal so ausprobieren, wie du das dargestellt hast und meine Ergebnisse dann hier posten. Aber ich denke mal, dass ich so schon gut weiterkomme...
Merci
EDITH meint: Konnte das Problem mit eurer Hilfe loesen. Insbesondere danke an deepthroat. Konnte anhand deines Code-Beispiels eine Loesung zusammenbasteln und es funktioniert nun alles wie gewollt.Geändert von Valas (13.01.10 um 04:32 Uhr)
Ähnliche Themen
-
sort ArrayList - HashMap
Von TaJa im Forum JavaAntworten: 1Letzter Beitrag: 22.04.10, 22:42 -
PL/SQL: Collections sortieren
Von zuckerbrini im Forum Relationale DatenbanksystemeAntworten: 1Letzter Beitrag: 21.08.09, 08:03 -
Collections.sort als Inner Class erkennt Funktionen von zu sortierenden Obj. nicht
Von mc_gulasch im Forum JavaAntworten: 1Letzter Beitrag: 11.09.08, 11:46 -
ArrayList collections.sort() Problem./..
Von scaary im Forum JavaAntworten: 7Letzter Beitrag: 24.02.08, 17:22 -
ArrayList sortieren
Von mgd-one im Forum .NET ArchivAntworten: 8Letzter Beitrag: 31.01.04, 14:40





Zitieren

Login





