【问题标题】:How to sort list of strings where first comes strings with startWith then endWith如何对字符串列表进行排序,其中首先出现的字符串是startsWith然后是endsWith
【发布时间】:2018-09-08 03:07:20
【问题描述】:

我有字符串列表 例如

**united**abc
**united**abcd
abcd**united**
**united**abcde
asdasdad**united**
**united**a

它是根据字符串的长度排序的,但我的想法是排序

**united**a 
**united**abc
**united**abcd
**united**abcde
abcd**united**
asdasdad**united**

首先出现以united 开头的字符串,然后是以united 结尾的其他单词。但我仍然需要保持长度顺序。

我试过了,但这不起作用

 if (o1.name.toLowerCase().startsWith(query)) {
    return@Comparator  -1
  } else if (o2.name.toLowerCase().startsWith(query)) {
    return@Comparator  1
  } else {
    return@Comparator 0
  }

【问题讨论】:

  • 您需要 2 个比较器来提高可读性。一个访问另一个。您还需要考虑 o1 和 o2 都包含联合的情况

标签: java sorting collections


【解决方案1】:

使用Comparator.comparingthenComparing 方法组合比较器条件会更清晰,因此更不容易出错:

list.sort(Comparator.comparing((String str) -> !str.startsWith(query))
        .thenComparing(str -> !str.endsWith(query))
        .thenComparingInt(String::length)
        .thenComparing(Comparator.naturalOrder()));

! 符号的原因是我们的 true 将排在 false 之前。

【讨论】:

    【解决方案2】:

    比较器的问题在于,当两个输入都以query 字符串开头或结尾时,它违反了约束。例如,当o1o2name 都以"united" 开头时,您的比较器将为o1.compareTo(o2) 及其相反的o2.compareTo(o1) 返回-1,这是不一致的,因此会抛出排序算法。

    您需要修改代码以检查双方的startsWithendsWith,然后再继续:

    String n1 = o1.name.toLowerCase();
    String n2 = o2.name.toLowerCase();
    // Both startsWith / both endsWith
    if ((n1.startsWith(query) && n2.startsWith(query))
    ||  (n1.endsWith(query) && n2.endsWith(query))) {
        return Integer.compare(n1.length(), n2.length());
    }
    // Only one startsWith
    if (n1.startsWith(query)) {
        return -1;
    }
    if (n2.startsWith(query)) {
        return 1;
    }
    // only one endsWith
    if (n1.endsWith(query)) {
        return 1;
    }
    if (n2.endsWith(query)) {
        return -1;
    }
    

    【讨论】:

    • OP 想要根据长度进行二次排序,所以不要使用n1.compareTo(n2),而是使用n2.length() - n1.length()
    • @DodgyCodeException 是的,我完全错过了那部分。谢谢!
    【解决方案3】:

    您需要 3 个比较器才能提高可读性。
    找出是否团结在前面,然后按此排序。
    找出团结是否在后面,然后按此排序。
    如果不包含统一的,则查找顺序,或者两者具有相同的统一优先级,例如。 o1.unitedFront && o2.unitedFront 或 o1.unitedEnd && o2.unitedEnd.

    您目前没有考虑两个字符串都包含 united 的情况,因为您假设如果第一个包含,则其他不包含。

    【讨论】:

      猜你喜欢
      • 2012-08-12
      • 1970-01-01
      • 2014-01-10
      • 2023-03-25
      • 1970-01-01
      • 2015-12-09
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多