如何基于搜索关键词对ArrayList进行自定义排序
实现前缀优先的自定义排序逻辑
我完全get到你的需求:要把以指定关键词开头的元素优先排在前面,剩下的元素再按常规字母顺序排列,而且从你的例子来看,匹配的时候应该是不区分大小写的(毕竟你搜的是el,目标元素是Eloise、Elon)。
你之前的代码问题在于,只对截取后的前缀做了字母序比较,但没有区分「是否匹配前缀」这个最高优先级——比如"Babel"的前两个字符是"Ba",按字母序比"El"小,所以会被排到前面,这显然和你想要的结果相反。
正确的实现思路
咱们可以把排序逻辑拆成三层优先级:
- 优先判断元素是否匹配前缀:匹配的元素必须排在不匹配的前面
- 如果两个元素都匹配前缀,按它们的原字符串字母序排序
- 如果两个元素都不匹配前缀,同样按原字符串字母序排序
具体代码实现
这里我们可以用regionMatches来高效判断前缀匹配(避免全字符串转小写,性能更优),或者直接转小写后用startsWith,两种方式都可以:
// 先把搜索关键词转成小写,统一匹配规则(如果需要区分大小写可以跳过这步) String searchPrefix = finalS.toLowerCase(); users.sort((o1, o2) -> { String name1 = o1.getNickname(); String name2 = o2.getNickname(); // 不区分大小写判断是否以指定前缀开头 boolean isMatch1 = name1.regionMatches(true, 0, searchPrefix, 0, searchPrefix.length()); boolean isMatch2 = name2.regionMatches(true, 0, searchPrefix, 0, searchPrefix.length()); // 优先级1:匹配的排前面 if (isMatch1 && !isMatch2) { return -1; // o1匹配,o2不匹配,o1在前 } else if (!isMatch1 && isMatch2) { return 1; // o2匹配,o1不匹配,o2在前 } // 优先级2:同组内按原字符串自然排序 return name1.compareTo(name2); });
如果需要区分大小写的匹配,只需要把regionMatches的第一个参数改成false,或者直接用:
boolean isMatch1 = name1.startsWith(finalS); boolean isMatch2 = name2.startsWith(finalS);
验证结果
用你的测试列表["Babel", "Isabelle", "Elon", "Eloise"]和关键词"el",运行这段代码后,排序结果就是:Eloise → Elon → Babel → Isabelle,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Vodet
相关产品推荐
相关产品推荐

