自定义排序方式,A 在 a 之前,B 在 b 之前

Vis*_*tna 9 java sorting java-8 java-stream

我有一个像这样的颜色列表:

粉色、蓝色、红色、蓝色、灰色、绿色、紫色、黑色...等

List<String> listOfColors =  Arrays.asList("Pink", "Blue", "Red", "blue", "Grey", "green", "purple", "black");
Run Code Online (Sandbox Code Playgroud)

有一些中间操作,比如过滤一些水果颜色,现在我留下了过滤结果,我希望它们按顺序排序:

蓝、黑、蓝、灰、绿、粉、紫、红

我试过了 :

List<String> listOfColors =  Arrays.asList("Pink", "Blue", "Red", "blue", "Grey", "green", "purple", "black");
Run Code Online (Sandbox Code Playgroud)

它没有按预期工作。

输出如下:

黑、蓝、蓝、绿、灰、粉、紫、红

我想要以下内容:

蓝、黑、蓝、灰、绿、粉、紫、红

Vis*_*tna 8

您可以使用RuleBasedCollat​​or来定义您自己的规则。

自定义规则示例:

String rules = "< c,C < b,B";
Run Code Online (Sandbox Code Playgroud)

上面的规则被解码为在比较字符串时,大写和小写C都出现在大写和小写之前B

String customRules = "<A<a<B<b<C<c<D<d<E<e<F<f<G<g<H<h<I<i<J<j<K<k<L<l<M<m<N<n<O<o<P<p<Q<q<R<r<S<s<T<t<U<u<V<v<X<x<Y<y<Z<z";
RuleBasedCollator myRuleBasedCollator = new RuleBasedCollator(customRules);
Collections.sort(listOfColors,myRuleBasedCollator);
System.out.println(listOfColors);
Run Code Online (Sandbox Code Playgroud)

输出:

[Blue, black, blue, Grey, green, Pink, purple, Red]
Run Code Online (Sandbox Code Playgroud)

编辑:customRules您可以使用下面的代码来生成它,而不是手工编写。

String a = IntStream.range('a', 'z' + 1).mapToObj(c -> Character.toString((char) c))
        .flatMap(ch -> Stream
            .of("<", ch.toUpperCase(), "<", ch)).collect(Collectors.joining(""));
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢 `IntStream.rangeClosed('a', 'z').flatMap(c -&gt; IntStream.of(c,Character.toUpperCase(c))) .mapToObj(c -&gt; Character.toString((char)) c)) .collect(Collectors.joining("&lt;", "&lt;", ""));` (3认同)
  • 创建 `String customRules` 可以使用 `IntStream` 自动执行: `IntStream.range('a', 'z' + 1) .mapToObj(Character::toString) .flatMap(ch -&gt; Stream.of("&lt;", ch.toUpperCase(), "&lt;", ch)) .collect(Collectors.joining(""))` (2认同)

Dan*_*lBK 7

我的解决方案是通过使用Comparator.thenComparing()方法分两步使用排序。

首先,仅通过忽略大小写的第一个字符来比较字符串。因此,具有相同第一个字符(无论哪种情况)的组到目前为止仍未排序。然后在第二步中应用正常的字母排序来对那些未排序的子组进行排序。

List<String> listOfColors =  Arrays.asList("Pink", "Blue", "Red", "blue", "Grey", "green", "purple", "black");
Comparator<String> comparator = Comparator.comparing(s -> 
        Character.toLowerCase(s.charAt(0)));
listOfColors.sort(comparator.thenComparing(Comparator.naturalOrder()));
System.out.println(listOfColors);
Run Code Online (Sandbox Code Playgroud)

也许它仍然可以优化,但它给出了想要的结果:

[Blue, black, blue, Grey, green, Pink, purple, Red]