Saya memiliki Daftar warna seperti ini:
Pink, Biru, Merah, biru, Abu-abu, hijau, ungu, hitam ... dll
List<String> listOfColors = Arrays.asList("Pink", "Blue", "Red", "blue", "Grey", "green", "purple", "black");
Ada beberapa operasi perantara seperti memfilter beberapa warna buah, sekarang saya dibiarkan dengan hasil yang disaring di mana saya ingin mereka diurutkan secara berurutan:
Biru, hitam, biru, abu-abu, hijau, merah muda, ungu, merah
Saya telah mencoba :
List<String> collect = listOfColors.stream().sorted(String::compareToIgnoreCase)
.collect(Collectors.toList());
Itu tidak bekerja seperti yang diharapkan.
Outputnya adalah sebagai berikut:
hitam, Biru, biru, hijau, Abu-abu, Merah Muda, ungu, Merah
Saya ingin yang berikut ini:
Biru, hitam, biru, abu-abu, hijau, merah muda, ungu, merah
java
sorting
java-8
java-stream
Vishwa Ratna
sumber
sumber
a
sebelumu
jadi hasilnya benar[black, Blue, blue, green, Grey, Pink, purple, Red]
@ chrylis-onstrike-Jawaban:
Solusi saya adalah menggunakan penyortiran dalam dua langkah dengan menggunakan
Comparator.thenComparing()
metode ini.Pertama, bandingkan Strings hanya dengan huruf pertama yang mengabaikan case. Jadi kelompok-kelompok dengan karakter pertama yang sama (tidak peduli kasus apa) tetap tidak disortir sejauh ini. Kemudian pada langkah kedua terapkan penyortiran alfabet normal untuk mengurutkan subkelompok yang tidak disortir.
Mungkin masih bisa dioptimalkan, tetapi memberikan hasil yang diinginkan:
sumber
Comparator
. Tapi ya, ini mengasumsikan hanya membandingkan karakter pertama dari String yang tidak banyak ditekankan oleh OP.Anda bisa menggunakan RuleBasedCollator untuk mendefinisikan Aturan Anda sendiri.
Contoh aturan khusus :
Keluaran:
Sunting: Alih-alih menulis
customRules
dengan tangan, Anda dapat menggunakan kode di bawah ini untuk membuatnya.sumber
String customRules
bisa otomatisme denganIntStream
:IntStream.range('a', 'z' + 1) .mapToObj(Character::toString) .flatMap(ch -> Stream.of("<", ch.toUpperCase(), "<", ch)) .collect(Collectors.joining(""))
.mapToObj(Character::toString)
tidak akan terselesaikan, saya kira Anda perlu menggunakan.mapToObj(c -> Character.toString((char) c))
mapToObj(Character::toString)
hanya berfungsi di Java 11 atau lebih baru.mapToObj(Character::toString)
tidak mendapatkan penyelesaian, tetapi saya menyukai ide itu sehingga saya akhirnya melakukan casting seperti.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("<", "<", ""));
Anda memerlukan metode yang pertama-tama melakukan perbandingan tidak sensitif huruf pada setiap huruf, lalu jika ada kecocokan yang melakukan perbandingan sensitif huruf pada setiap huruf:
Anda dapat meneruskan metode ini ke
Stream.sorted
.sumber