按搜索关键字对 ArrayList 进行排序
Sort ArrayList by search keyword
我有一个包含此值的 ArrayList
"Babel"
"Isabelle"
"Elon"
"Eloise"
我在搜索中输入“el”,我对列表进行排序,我想要这个结果
"Eloise"
"Elon"
"Babel"
"Isabelle"
因为 "Eloise"
从我的搜索开始 [=16=] 比如 "Elon"
然后 "Babel"
因为字母顺序在 "Isabelle"
之前
我不知道如何按数组的第一个字符排序 我尝试对名称进行子字符串化
users.sort((o1, o2) -> {
String name1 = o1.getNickname();
String name2 = o2.getNickname();
if (o1.getNickname().length() >= finalS.length()) {
name1 = o1.getNickname().substring(0, finalS.length());
}
if (o2.getNickname().length() >= finalS.length()) {
name2 = o2.getNickname().substring(0, finalS.length());
}
return name1.compareTo(name2);
});
但是这个 return name1.compareTo(name2);
比较切割后的字符串并按字母顺序排列。
我尝试将其添加到子字符串下方
if (name1.contains(finalS)) return 1;
或
if (name2.contains(finalS)) return 1;
没有工作Babel
总是在第一位
你的比较器应该看起来像这样:
首先对以您的搜索开头的内容进行排序,然后对仅包含它们的内容进行排序。但最好的搜索方法是使用 diff-match-patch (https://github.com/google/diff-match-patch).
public int compare(User o1, User o2) {
String search = YOUR_SEARCH.toLowerCase();
String name1 = o1.getNickname().toLowerCase();
String name2 = o2.getNickname().toLowerCase();
int i = Boolean.compare(name2.startsWith(search), name1.startsWith(search));
if (i != 0)
return i;
i = Boolean.compare(name2.contains(search), name1.contains(search));
if (i != 0)
return i;
return name2.compareTo(name1);
}
在大多数情况下,Comparator
接口中的工厂方法是合适的,可以减少对比较器的两个参数应用操作的冗余。
由于您的输入是 "el"
但名称以大写字母开头,您需要不区分大小写的部分匹配,然后按字符串的自然顺序排序。
List<String> users = Arrays.asList("Babel", "Isabelle", "Elon", "Eloise");
String finalS = "el";
users.sort(Comparator.comparing(
(String u) -> !finalS.regionMatches(true, 0, u, 0, finalS.length()))
.thenComparing(Comparator.naturalOrder()));
users.forEach(System.out::println);
Eloise
Elon
Babel
Isabelle
因为显然有一个 class User
你想比较它的 Nickname
属性,完整的排序代码看起来像
users.sort(Comparator.comparing(User::getNickname, Comparator.comparing(
(String u) -> !finalS.regionMatches(true, 0, u, 0, finalS.length()))
.thenComparing(Comparator.naturalOrder())));
我有一个包含此值的 ArrayList
"Babel"
"Isabelle"
"Elon"
"Eloise"
我在搜索中输入“el”,我对列表进行排序,我想要这个结果
"Eloise"
"Elon"
"Babel"
"Isabelle"
因为 "Eloise"
从我的搜索开始 [=16=] 比如 "Elon"
然后 "Babel"
因为字母顺序在 "Isabelle"
我不知道如何按数组的第一个字符排序 我尝试对名称进行子字符串化
users.sort((o1, o2) -> {
String name1 = o1.getNickname();
String name2 = o2.getNickname();
if (o1.getNickname().length() >= finalS.length()) {
name1 = o1.getNickname().substring(0, finalS.length());
}
if (o2.getNickname().length() >= finalS.length()) {
name2 = o2.getNickname().substring(0, finalS.length());
}
return name1.compareTo(name2);
});
但是这个 return name1.compareTo(name2);
比较切割后的字符串并按字母顺序排列。
我尝试将其添加到子字符串下方
if (name1.contains(finalS)) return 1;
或
if (name2.contains(finalS)) return 1;
没有工作Babel
总是在第一位
你的比较器应该看起来像这样: 首先对以您的搜索开头的内容进行排序,然后对仅包含它们的内容进行排序。但最好的搜索方法是使用 diff-match-patch (https://github.com/google/diff-match-patch).
public int compare(User o1, User o2) {
String search = YOUR_SEARCH.toLowerCase();
String name1 = o1.getNickname().toLowerCase();
String name2 = o2.getNickname().toLowerCase();
int i = Boolean.compare(name2.startsWith(search), name1.startsWith(search));
if (i != 0)
return i;
i = Boolean.compare(name2.contains(search), name1.contains(search));
if (i != 0)
return i;
return name2.compareTo(name1);
}
在大多数情况下,Comparator
接口中的工厂方法是合适的,可以减少对比较器的两个参数应用操作的冗余。
由于您的输入是 "el"
但名称以大写字母开头,您需要不区分大小写的部分匹配,然后按字符串的自然顺序排序。
List<String> users = Arrays.asList("Babel", "Isabelle", "Elon", "Eloise");
String finalS = "el";
users.sort(Comparator.comparing(
(String u) -> !finalS.regionMatches(true, 0, u, 0, finalS.length()))
.thenComparing(Comparator.naturalOrder()));
users.forEach(System.out::println);
Eloise
Elon
Babel
Isabelle
因为显然有一个 class User
你想比较它的 Nickname
属性,完整的排序代码看起来像
users.sort(Comparator.comparing(User::getNickname, Comparator.comparing(
(String u) -> !finalS.regionMatches(true, 0, u, 0, finalS.length()))
.thenComparing(Comparator.naturalOrder())));