我在排序包含整数的字符串时遇到问题。如果我使用下面的代码,我会得到如下排序: 1some,2some,20some,21some,3some,some
但我希望它排序如下: 1some,2some,3some,20some,21some,some
我该怎么做?
谢谢!
Collections.sort(selectedNodes,
new Comparator<DefaultMutableTreeNode>() {
@Override
public int compare(DefaultMutableTreeNode o1,
DefaultMutableTreeNode o2) {
return o1.getUserObject().toString()
.compareTo(o2.getUserObject().toString());
}
});
答案 0 :(得分:7)
以下是有关如何执行此操作(未特别优化)的自包含示例:
final Pattern p = Pattern.compile("^\\d+");
String[] examples = {
"1some", "2some", "20some", "21some", "3some", "some", "1abc", "abc"
};
Comparator<String> c = new Comparator<String>() {
@Override
public int compare(String object1, String object2) {
Matcher m = p.matcher(object1);
Integer number1 = null;
if (!m.find()) {
return object1.compareTo(object2);
}
else {
Integer number2 = null;
number1 = Integer.parseInt(m.group());
m = p.matcher(object2);
if (!m.find()) {
return object1.compareTo(object2);
}
else {
number2 = Integer.parseInt(m.group());
int comparison = number1.compareTo(number2);
if (comparison != 0) {
return comparison;
}
else {
return object1.compareTo(object2);
}
}
}
}
};
List<String> examplesList = new ArrayList<String>(Arrays.asList(examples));
Collections.sort(examplesList, c);
System.out.println(examplesList);
<强>输出强>
[1abc, 1some, 2some, 3some, 20some, 21some, abc, some]
<强>解释强>
Pattern
来推断某个数字是否在String
的起始位置。String
中没有,则将其与第二个String
进行比较。Integer
String
而不是整个String
,因此会产生数字比较,而不是字典比较答案 1 :(得分:3)
您的解决方案位于The Alphanum Algorithm,您可以实施this
答案 2 :(得分:3)
首先制作一个字母数字比较器,将字符串拆分为String或Integer部分。
public class AlphaNumericalComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
List<Object> parts1 = partsOf(o1);
List<Object> parts2 = partsOf(o2);
while (!parts1.isEmpty() && !parts2.isEmpty()) {
Object part1 = parts1.remove(0);
Object part2 = parts2.remove(0);
int cmp = 0;
if (part1 instanceof Integer && part2 instanceof Integer) {
cmp = Integer.compare((Integer)part1, (Integer)part2);
} else if (part1 instanceof String && part2 instanceof String) {
cmp = ((String) part1).compareTo((String) part2);
} else {
cmp = part1 instanceof String ? 1 : -1; // XXXa > XXX1
}
if (cmp != 0) {
return cmp;
}
}
if (parts1.isEmpty() && parts2.isEmpty()) {
return 0;
}
return parts1.isEmpty() ? -1 : 1;
}
private List<Object> partsOf(String s) {
List<Object> parts = new LinkedList<>();
int pos0 = 0;
int pos = 0;
boolean wasDigit = false;
while (true) {
if (pos >= s.length()
|| Character.isDigit(s.charAt(pos)) != wasDigit) {
if (pos > pos0) {
String part = s.substring(pos0, pos);
parts.add(wasDigit? Integer.valueOf(part) : part);
pos0 = pos;
}
if (pos >= s.length()) {
break;
}
wasDigit = !wasDigit;
}
++pos;
}
return parts;
}
};
然后在你自己的比较器中使用这个比较器,在Java 8中你可以简单地使用Comparator的静态方法。
答案 3 :(得分:0)
您需要实现自己的Comparator
来执行此类自定义排序。默认的String.compareTo()
方法似乎在字符前对数字进行排序。将0
中的20some
与s
中的3some
进行比较时,0
具有更高的排序优先级,因此整个单词首先排序。
你需要做的是:尝试将字符串分成数字和字符部分。这是一项艰巨的任务,因为那些String
可能包含许多这些部分(或者不是这些部分?)。您可以使用像Alphanum
这样的算法,Murtaza已经向您展示了这些算法
如果您想自己实现它,可以检查数字部分的结束位置。然后使用int
将其解析为Integer.parse()
。比较int
部分String
中的{{1}}部分,然后比较其余部分。那可能不是最专业的解决方案,但作为一个初学者,你可能想要自己制作这些东西来学习它。
答案 4 :(得分:0)
您不能使用默认的String compareTo(),而是需要按照以下算法比较字符串。
重复这些步骤。
答案 5 :(得分:0)
您可以使用正则表达式在一行中创建它的核心来提取数字部分:
Collections.sort(selectedNodes, new Comparator<DefaultMutableTreeNode>() {
@Override
public int compare(DefaultMutableTreeNode o1,
DefaultMutableTreeNode o2) {
return Integer.parseInt(o1.getUserObject().toString().replaceAll("\\D", "")) -
Integer.parseInt(o2.getUserObject().toString().replaceAll("\\D", ""));
}
});
答案 6 :(得分:0)
这是Java的有效解决方案。如果您对代码有任何建议,请在我的Gist上告诉我。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class FB {
public static int comparator(String s1, String s2) {
String[] pt1 = s1.split("((?<=[a-z])(?=[0-9]))|((?<=[0-9])(?=[a-z]))");
String[] pt2 = s2.split("((?<=[a-z])(?=[0-9]))|((?<=[0-9])(?=[a-z]))");
//pt1 and pt2 arrays will have the string split in alphabets and numbers
int i=0;
if(Arrays.equals(pt1, pt2))
return 0;
else{
for(i=0;i<Math.min(pt1.length, pt2.length);i++)
if(!pt1[i].equals(pt2[i])) {
if(!isNumber(pt1[i],pt2[i])) {
if(pt1[i].compareTo(pt2[i])>0)
return 1;
else
return -1;
}
else {
int nu1 = Integer.parseInt(pt1[i]);
int nu2 = Integer.parseInt(pt2[i]);
if(nu1>nu2)
return 1;
else
return -1;
}
}
}
if(pt1.length>i)
return 1;
else
return -1;
}
private static Boolean isNumber(String n1, String n2) {
// TODO Auto-generated method stub
try {
int nu1 = Integer.parseInt(n1);
int nu2 = Integer.parseInt(n2);
return true;
}
catch(Exception x) {
return false;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] examples = {"1some", "2some", "20some", "21some", "3some", "some", "1abc", "abc"};
List<String> values = new ArrayList<String>(Arrays.asList(examples));
System.out.println(values);
Comparator<String> com = (o1,o2) -> {return comparator(o1,o2);}; //lambda expression
Collections.sort(values,com);
System.out.println(values);
}
}
输出:
[1some, 2some, 20some, 21some, 3some, some, 1abc, abc]
[1abc, 1some, 2some, 3some, 20some, 21some, abc, some]
答案 7 :(得分:0)
如果您知道模式始终为NUMALPHA或ALPHANUM,并且alpha始终相同:
if(str1.length() != str2.length()){
return str1.length() - str2.length();
}
return str1.compareTo(str2);
答案 8 :(得分:0)
如果您有字母数字字符串数组,则可以使用
直接对其进行排序Arrays.sort(Array_name)
和 然后打印:
for(String a : Array_name)
System.out.print(a);
答案 9 :(得分:0)
如何使用Java在Java中对字符串,字母数字和数值进行排序 比较器
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AlphaNumericSorting {
public static void main(String[] args) {
final Pattern p = Pattern.compile("^\\d+");
String[] examples = { "CD", "DE", "0A", "0B", "0C", "12", "0K", "TA", "0D", "01", "02", "11", "AB", "MN" };
Comparator<String> c = new Comparator<String>() {
@Override
public int compare(String object1, String object2) {
Matcher m = p.matcher(object1);
Integer number1 = null;
if (!m.find()) {
Matcher m1 = p.matcher(object2);
if (m1.find()) {
return object2.compareTo(object1);
} else {
return object1.compareTo(object2);
}
} else {
Integer number2 = null;
number1 = Integer.parseInt(m.group());
m = p.matcher(object2);
if (!m.find()) {
// return object1.compareTo(object2);
Matcher m1 = p.matcher(object1);
if (m1.find()) {
return object2.compareTo(object1);
} else {
return object1.compareTo(object2);
}
} else {
number2 = Integer.parseInt(m.group());
int comparison = number1.compareTo(number2);
if (comparison != 0) {
return comparison;
} else {
return object1.compareTo(object2);
}
}
}
}
};
List<String> examplesList = new ArrayList<String>(Arrays.asList(examples));
Collections.sort(examplesList, c);
System.out.println(examplesList);
}
}
输出:-
[AB,CD,DE,MN,TA,0A,0B,0C,0D,0K,01、02、11、12 ]
答案 10 :(得分:-5)
String [] str = new String[]{"1some", "2some", "20some", "21some", "3some", "some"};
List<String> list = Arrays.asList(str);
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
System.out.println(list);