Java TreeMap (Komparator) und erhalten Methode ignoriert den Vergleicher

8
%Vor%

Mein Problem ist, wie man die Methode get (id) verwendet, die den gegebenen Vergleicher ignoriert. Ich möchte, dass die Karte von Case Insensitive sortiert wird, aber ich möchte, dass die Groß- / Kleinschreibung beachtet wird, wenn ich die Werte mit einem bestimmten Schlüssel abrufe.

    
d0pe 23.11.2009, 11:51
quelle

7 Antworten

8

Ich denke, die Antwort ist einfach. Implementieren Sie einen eigenen Vergleicher, der eine Sortierung ohne Berücksichtigung der Groß- / Kleinschreibung vornimmt, aber NOT gibt 0 für "A" und "a" zurück ... sortieren Sie sie auch.

Das Problem ist, dass Ihr Vergleicher 0 für den Vergleich ("A", "a") zurückgibt, was bedeutet, dass es derselbe Schlüssel ist, soweit es die Karte betrifft.

Verwenden Sie einen Vergleicher wie:

%Vor%

Dann werden alle Tasten unabhängig von der Groß- / Kleinschreibung eingegeben und "a" und "A" werden weiterhin zusammen sortiert.

Mit anderen Worten, get ("a") gibt Ihnen einen anderen Wert als get ("A") ... und beide werden in keySet () Iteratoren angezeigt. Sie werden nur zusammen sortiert.

    
PSpeed 23.11.2009, 12:41
quelle
6

Wenn Sie in einer TreeMap zwei Schlüssel a und b (in dieser Reihenfolge) hinzufügen, sodass compare (a, b) 0 zurückgibt, wird der zuletzt hinzugefügte Eintrag (b) den ersten (a) überschreiben.

In Ihrem Fall bedeutet dies, dass es niemals eine Verwendung für die Groß- / Kleinschreibung (id) geben wird.

zitieren Ссылка

  

Beachten Sie, dass die Sortierung, die von einer sortierten Zuordnung verwaltet wird (ob ein expliziter Komparator bereitgestellt wird oder nicht), konsistent mit equals sein muss, wenn diese sortierte Zuordnung die Map-Schnittstelle korrekt implementieren soll. (Siehe Vergleicher oder Komparator für eine genaue Definition von konsistent mit equals.) Dies liegt daran, dass die Map-Schnittstelle als Gleichheitsoperation definiert ist, eine Map jedoch alle Schlüsselvergleiche mithilfe der compareTo (oder compare) -Methode ausführt, also zwei Schlüssel die mit dieser Methode als gleich angesehen werden, sind vom Standpunkt der sortierten Karte gleich. Das Verhalten einer sortierten Karte ist gut definiert, selbst wenn ihre Reihenfolge nicht mit Gleichem übereinstimmt. Es entspricht nur nicht dem allgemeinen Vertrag der Map-Schnittstelle.

Das ist wahrscheinlich nicht das, was Sie wollen.

Wenn die Map vergleichsweise klein ist und Sie die sortierten Einträge nicht sehr oft abrufen müssen, besteht die Lösung darin, eine HashMap (oder eine TreeMap ohne explizite Einstellung des Vergleichers) zu verwenden und die Einträge bei der Sortierung nach Groß- und Kleinschreibung zu sortieren Sie brauchen sie bestellt.

    
Buhb 23.11.2009 12:12
quelle
1

Sie müssen dafür zwei separate TreeMaps verwenden, die denselben Inhalt aber unterschiedliche Komparatoren haben.

    
Tom Bartel 23.11.2009 12:01
quelle
1

vielleicht wird es den Job machen:

%Vor%     
Mirek Pluta 23.11.2009 12:05
quelle
1

Sie benötigen eine Multimap : Jeder Eintrag dieser Multimap enthält die Groß- / Kleinschreibung und eine andere Map mit den Originalschlüsseln als Wert.

Es gibt viele frei verwendbare Implementierungen von Multimaps wie Common Collections , Google Sammlungen usw.

    
dfa 23.11.2009 12:24
quelle
0

Zusätzlich zu all den anderen Antworten und dem Einvernehmen, dass es unmöglich ist, eine einzige TreeMap Struktur mit verschiedenen Komparatoren zu haben:

Aus Ihrer Frage verstehe ich, dass Sie zwei Anforderungen haben: Das Datenmodell muss Groß- und Kleinschreibung beachten (Sie möchten die Groß- und Kleinschreibung bei Verwendung von get() ), der Präsentator muss Groß- und Kleinschreibung beachten Präsentation ist nur eine Annahme).

Nehmen wir an, wir füllen die Map mit den Zuordnungen (aa, obj1), (aA, obj2), (Aa, obj3), (AA, obj4). Der Iterator liefert die Werte in folgender Reihenfolge: (obj4, obj3, obj2, obj1) (*). Welche Reihenfolge erwarten Sie jetzt, wenn die Map ohne Groß- und Kleinschreibung sortiert wurde? Alle vier Schlüssel wären gleich und die Reihenfolge nicht definiert. Oder suchen Sie nach einer Lösung, die die Sammlung {obj1, obj2, obj3, obj4} für den Schlüssel 'AA' auflösen würde? Aber das ist ein anderer Ansatz.

SO ermutigt die Community, ehrlich zu sein: Daher ist mein Rat an dieser Stelle, sich erneut Ihre Anforderung anzusehen:)

(*) nicht getestet, angenommen, dass "A" & lt; 'a' = wahr.

    
Andreas_D 23.11.2009 13:21
quelle
-1

Verwenden Sie floorEntry und dann higherEntry in einer Schleife, um die Einträge ohne Berücksichtigung der Groß- und Kleinschreibung zu finden ; Stoppen Sie, wenn Sie die genaue Schlüsselübereinstimmung finden.

    
Andrew Duffy 23.11.2009 12:08
quelle

Tags und Links