Ich habe eine Liste solcher Farben:
Pink, Blau, Rot, Blau, Grau, Grün, Lila, Schwarz ... usw.
List<String> listOfColors = Arrays.asList("Pink", "Blue", "Red", "blue", "Grey", "green", "purple", "black");
Es gibt einige Zwischenoperationen wie das Filtern einiger Fruchtfarben. Jetzt habe ich gefilterte Ergebnisse, in denen sie sortiert werden sollen:
Blau, Schwarz, Blau, Grau, Grün, Pink, Lila, Rot
Ich habe versucht :
List<String> collect = listOfColors.stream().sorted(String::compareToIgnoreCase)
.collect(Collectors.toList());
Es funktioniert nicht wie erwartet.
Die Ausgabe ist die folgende:
schwarz, blau, blau, grün, grau, pink, lila, rot
Ich möchte folgendes:
Blau, Schwarz, Blau, Grau, Grün, Pink, Lila, Rot
java
sorting
java-8
java-stream
Vishwa Ratna
quelle
quelle
a
ist vorheru
so ist das Ergebnis korrekt[black, Blue, blue, green, Grey, Pink, purple, Red]
@ chrylis-onstrike-Antworten:
Meine Lösung besteht darin, die Sortierung in zwei Schritten mithilfe der
Comparator.thenComparing()
Methode zu verwenden.Vergleichen Sie zunächst die Zeichenfolgen nur mit dem ersten Zeichen, wobei die Groß- und Kleinschreibung ignoriert wird. Daher bleiben die Gruppen mit demselben ersten Zeichen (egal in welchem Fall) bisher unsortiert. Wenden Sie dann im zweiten Schritt die normale alphabetische Sortierung an, um diese unsortierten Untergruppen zu sortieren.
Vielleicht kann es noch optimiert werden, aber es gibt das gewünschte Ergebnis:
quelle
Comparator
. Aber ja, dies setzt voraus, dass nur das erste Zeichen des Strings verglichen wird, auf das das OP auch nicht viel Wert gelegt hat.Mit RuleBasedCollator können Sie Ihre eigenen Regeln definieren.
Beispiel für eine benutzerdefinierte Regel:
Ausgabe:
Bearbeiten: Anstatt das
customRules
von Hand zu schreiben , können Sie es mit dem folgenden Code generieren.quelle
String customRules
kann Automatismus sein mitIntStream
:IntStream.range('a', 'z' + 1) .mapToObj(Character::toString) .flatMap(ch -> Stream.of("<", ch.toUpperCase(), "<", ch)) .collect(Collectors.joining(""))
.mapToObj(Character::toString)
wird nicht gelöst, ich denke, Sie müssen verwenden.mapToObj(c -> Character.toString((char) c))
mapToObj(Character::toString)
funktioniert nur in Java 11 oder neuer.mapToObj(Character::toString)
wurde nicht gelöst, aber ich mochte die Idee, also mache ich am Ende Casting wie.mapToObj(c -> Character.toString((char) c))
IntStream.rangeClosed('a', 'z').flatMap(c -> IntStream.of(c,Character.toUpperCase(c))) .mapToObj(c -> Character.toString((char)c)) .collect(Collectors.joining("<", "<", ""));
Sie benötigen eine Methode, die zuerst einen Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung für jeden Buchstaben durchführt. Wenn dann eine Übereinstimmung vorliegt, führen Sie für jeden Buchstaben einen Vergleich mit Groß- und Kleinschreibung durch:
Sie können diese Methode dann an übergeben
Stream.sorted
.quelle