Java android列表字符串带有数字和国家/地区字母的排序字符串
我无法将我的字符串与我想要的地址进行排序Ąraków Medyczna 1 Kraków Medyczna 2,Kraków Medyczna 13。但在第一个我有:克拉科夫医学院2号,克拉科夫医学院13号,卡拉科夫医学院1号,第二个我有:克拉科夫医学院1号,克拉科夫医学院13号,克拉科夫医学院2号Java android列表字符串带有数字和国家/地区字母的排序字符串,java,Java,我无法将我的字符串与我想要的地址进行排序Ąraków Medyczna 1 Kraków Medyczna 2,Kraków Medyczna 13。但在第一个我有:克拉科夫医学院2号,克拉科夫医学院13号,卡拉科夫医学院1号,第二个我有:克拉科夫医学院1号,克拉科夫医学院13号,克拉科夫医学院2号 ArrayList<String> names = new ArrayList<String>(); names.add("Kraków, Medyczna 13"); na
ArrayList<String> names = new ArrayList<String>();
names.add("Kraków, Medyczna 13");
names.add("Ąraków, Medyczna 1");
names.add("Kraków, Medyczna 2");
Collections.sort(names);
Collections.sort(names, Collator.getInstance(new Locale("PL")));
for(String s : names){
System.out.println(s);
}
Collections.sort(names, new Comparator<String>() {
public int compare(String o1, String o2) {
String o1StringPart = o1.replaceAll("\\d", "");
String o2StringPart = o2.replaceAll("\\d", "");
if(o1StringPart.equalsIgnoreCase(o2StringPart))
{
return extractInt(o1) - extractInt(o2);
}
return o1.compareTo(o2);
}
int extractInt(String s) {
String num = s.replaceAll("\\D", "");
// return 0 if no digits found
return num.isEmpty() ? 0 : Integer.parseInt(num);
}
});
for(String s : names){
System.out.println(s);
}
ArrayList name=new ArrayList();
名称。添加(“Kraków,Medyczna 13”);
名称。添加(“Ąraków,Medyczna 1”);
名称。添加(“Kraków,Medyczna 2”);
集合。排序(名称);
Collections.sort(名称、Collator.getInstance(新语言环境(“PL”));
用于(字符串s:名称){
系统输出打印项次;
}
Collections.sort(名称,新的Comparator(){
公共整数比较(字符串o1、字符串o2){
字符串o1StringPart=o1.replaceAll(“\\d”,即“”);
字符串o2StringPart=o2.replaceAll(“\\d”,即“”);
if(o1StringPart.equalsIgnoreCase(o2StringPart))
{
返回extractInt(o1)-extractInt(o2);
}
返回o1。与(o2)相比;
}
int extractInt(字符串s){
字符串num=s.replaceAll(“\\D”和“);
//如果找不到数字,则返回0
返回num.isEmpty()?0:Integer.parseInt(num);
}
});
用于(字符串s:名称){
系统输出打印项次;
}
您的自定义比较器几乎没有问题,只是忘记了对波兰字符集使用正确的比较器。在正常字符串比较中,“Ą”位于“K”之后
改变
return o1.compareTo(o2);
到
您希望逐部分比较完全由数字(数字)和完全由非数字(文本)组成的部分 下面的比较循环(文本、数字?) 如果只有一个字符串以数字开头,则它的第一部分为空文本,将被视为较小的字符串
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
Pattern digits = Pattern.compile("\\d+");
Matcher m1 = digits.matcher(o1);
Matcher m2 = digits.matcher(o2);
int i1 = 0;
int i2 = 0;
while (i1 < o1.length() && i2 < o2.length()) {
boolean b1 = m1.find();
int j1 = b1 ? m1.start() : o1.length();
boolean b2 = m2.find();
int j2 = b2 ? m2.start() : o2.length();
String part1 = o1.substring(i1, j1);
String part2 = o2.substring(i2, j2);
int cmp = String.compareIgnoreCase(part1, part2);
if (cmp != 0) {
return;
}
if (b1 && b2) {
int num1 = Integer.parseInt(m1.group());
int num2 = Integer.parseInt(m2.group());
cmp = Integer.compare(num1, num2);
i1 = m1.end();
i2 = m2.end();
} else if (b1) {
return -1;
} else if (b2) {
return 1;
}
}
return 0;
}
});
由于java 9,有一个重载的String.replaceAll
,可以传递一个替换函数
不重复一个自我,更优雅一点:
Function<String, String> numFormatter = s -> s.replaceAll("\\d+",
mr -> String.format("%010d", Integer.parseInt(mr.group())));
Collections.sort(names, (o1, o2) ->
Strings.compareIgnoreCase(numFormatter.apply(o1), numFormatter.apply(o2.))
);
Collator是一个比较器,但具有给定语言的内置排序功能。它在重音字母上表现得更好。我在这里放弃了不区分大小写的比较,因为可能不需要它;否则使用String.toUpperCase(Locale)
这有点多,我不完全确定Android的java,也不确定代码是否可以编译(拼写错误),但请享受。请花点时间改进您的输入。代码的格式/缩进确实是一团糟,使得阅读变得比必要的困难得多。您希望其他人花时间来帮助您解决问题,因此请您花时间提出易于阅读的输入。@GhostCat I格式化我的代码可能与Better的重复。但是,您可能还想改进示例数据的格式。您可能需要两种方法的组合。在第一次尝试中,collator似乎工作不正常(可能Java中没有真正的Polish collator,标准实现将
Ą
视为大于K
),在第二次尝试中,您需要在比较数字之前提取和解析数字。
Collections.sort(names, (o1, o2) -> {
Pattern digits = Pattern.compile("\\d+");
Matcher m1 = digits.matcher(o1);
Matcher m2 = digits.matcher(o2);
int i1 = 0;
int i2 = 0;
while (i1 < o1.length() && i2 < o2.length()) {
boolean b1 = m1.find();
int j1 = b1 ? m1.start() : o1.length();
boolean b2 = m2.find();
int j2 = b2 ? m2.start() : o2.length();
String part1 = o1.substring(i1, j1);
String part2 = o2.substring(i2, j2);
int cmp = String.compareIgnoreCase(part1, part2);
if (cmp != 0) {
return;
}
if (b1 && b2) {
int num1 = Integer.parseInt(m1.group());
int num2 = Integer.parseInt(m2.group());
cmp = Integer.compare(num1, num2);
i1 = m1.end();
i2 = m2.end();
} else if (b1) {
return -1;
} else if (b2) {
return 1;
}
}
return 0;
});
Collections.sort(names, (o1, o2) ->
Strings.compareIgnoreCase(
o1.replaceAll("\\d+", mr -> String.format("%010d", Integer.parseInt(mr.group())),
o2.replaceAll("\\d+", mr -> String.format("%010d", Integer.parseInt(mr.group())))
);
Function<String, String> numFormatter = s -> s.replaceAll("\\d+",
mr -> String.format("%010d", Integer.parseInt(mr.group())));
Collections.sort(names, (o1, o2) ->
Strings.compareIgnoreCase(numFormatter.apply(o1), numFormatter.apply(o2.))
);
Locale locale = new Locale("pl", "PL");
Collator collator = Collator.getInstance(locale); // How to sort on special letters
Function<String, String> numFormatter = s -> s /*.toUpperCase(locale)*/ .replaceAll("\\d+",
mr -> String.format("%010d", Integer.parseInt(mr.group())));
Collections.sort(names, Comparator.comparing(numFormatter, collator));