【问题标题】:Ordering List by a specific character (Java 8)按特定字符排序的列表(Java 8)
【发布时间】:2019-02-11 12:55:32
【问题描述】:

我有以下列表:

List<String> fruits = new ArrayList<String>(Arrays.asList("Apple", "Banana", "Orange", "Watermelon", "Peach")); 

我需要在这个条件下订购它:

  1. 首先,包含字符“o”或“O”的那些
  2. 然后,其余的。

结果应该是:

Orange, Watermelon, Apple, Banana, Peach

如何在 Java 8 中做到这一点?

【问题讨论】:

  • 您可以将Collections.sort 与自行实现的比较器一起使用。 (JavaDoc)

标签: java list sorting java-8 comparator


【解决方案1】:

您可以使用比较器链。

List<String> fruits = new ArrayList<>(Arrays.asList(
                               "Apple", "Banana", "Orange", "Watermelon", "Peach"));
fruits.sort(Comparator.comparing((String s) -> !s.contains("O") && !s.contains("o"))
        .thenComparing(Comparator.naturalOrder()));
System.out.println(fruits.stream().collect(Collectors.joining(", ")));

第一个比较器查看字符串是否包含一个 O,使那些先行的,第二个比较器使用自然排序。

注意:Boolean.TRUE.compareTo(Boolean.FALSE) &gt; 0 所以为了让包含 O 的字符串先行,我用 ! 翻转它

打印出来

Orange, Watermelon, Apple, Banana, Peach

注意:在这种情况下,不需要new ArrayList&lt;&gt;( ... ),因为sort 不会更改元素的数量,只是重新排列它们。


编辑:基于@Holger 的建议。

如果首选稳定的排序,即尽可能保持顺序不变。

List<String> fruits = Arrays.asList(
        "Watermelon", "Peach", "Orange", "Banana", "Apple");
fruits.sort(Comparator.comparing((String s) -> !s.contains("O") && !s.contains("o")));
System.out.println(fruits.stream().collect(Collectors.joining(", ")));

打印

Watermelon, Orange, Peach, Banana, Apple

【讨论】:

  • 据我所知,问题中没有要求“其余的”按自然顺序排序。所以你可以简单地使用Comparator.comparing(s -&gt; !s.toUpperCase().contains("O")),将带有O的那些移动到前面并保持它们的相对顺序不变。另一种选择是fruits.sort(Comparator.comparing(Pattern.compile("(?i)o").asPredicate().negate() ::test));,它避免为每次比较创建所有字符串的大写副本。这可能会为更大的列表和/或更大的字符串带来回报。
  • @Holger 编译 Pattern 需要被缓存,否则会贵很多倍。我想我不依赖比较器的使用是稳定的,因为它取决于上下文,例如对于 TreeSet,它会非常不同。该问题可能表明首选稳定的排序。
  • Pattern 在整个操作中只编译一次。当然,如果您多次执行此操作,您可能会考虑保留该模式,但这也适用于整个Comparator。您也可以改用Pattern.compile("o", Pattern.CASE_INSENSITIVE) 来降低模式初始化的成本。但无论如何,对于这样一个微不足道的模式,准备工作并不比复制一个字符串更昂贵,另一个比较器每次比较执行两次(最坏情况下大约有 n×log n 次比较)......
猜你喜欢
  • 2020-07-17
  • 2017-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-20
  • 1970-01-01
相关资源
最近更新 更多