【发布时间】:2011-09-27 10:27:28
【问题描述】:
有一些值,例如 AB、A012B、CD、1、10、01、9 我必须对它们进行排序 输出应该是 01,1,9,10,A012B,AB,CD 可以使用任何集合 我正在尝试使用 collection.sort 功能 但它认为一切都是字符串 和打印像 01,1,10,9,A012B,AB,CD 这不是我的要求...请帮助
【问题讨论】:
标签: java sorting collections
有一些值,例如 AB、A012B、CD、1、10、01、9 我必须对它们进行排序 输出应该是 01,1,9,10,A012B,AB,CD 可以使用任何集合 我正在尝试使用 collection.sort 功能 但它认为一切都是字符串 和打印像 01,1,10,9,A012B,AB,CD 这不是我的要求...请帮助
【问题讨论】:
标签: java sorting collections
//钓鱼技巧
List<String> values = new ArrayList<String>();
values.add("AB");
values.add("A012B");
values.add("CD");
values.add("1");
values.add("10");
values.add("01");
values.add("9");
values.add("I");
Collections.sort(values, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// TODO tweak the comparator here
try{
Integer integer1 = Integer.valueOf(o1);
Integer integer2 = Integer.valueOf(o2);
return integer1.compareTo(integer2);
}catch (java.lang.NumberFormatException e) {
return o1.compareTo(o2);
}
}
});
System.out.println(values);
}
//还不够???
//这是鱼
public static void main(String[] args) throws Exception {
List<String> values = new ArrayList<String>();
values.add("AB");
values.add("A012B");
values.add("CD");
values.add("1");
values.add("10");
values.add("01");
values.add("9");
int maxLen = 0;
for (String string : values) {
if (string.length() > maxLen) {
maxLen = string.length();
}
}
Collections.sort(values, new MyComparator(maxLen));
System.out.println(values);
}
public static class MyComparator implements Comparator<String> {
private int maxLen;
private static final String REGEX = "[0-9]+";
public MyComparator(int maxLen) {
this.maxLen = maxLen;
}
@Override
public int compare(String obj1, String obj2) {
String o1 = obj1;
String o2 = obj2;
// both numbers
if (o1.matches("[1-9]+") && o2.matches("[1-9]+")) {
Integer integer1 = Integer.valueOf(o1);
Integer integer2 = Integer.valueOf(o2);
return integer1.compareTo(integer2);
}
// both string
if (o1.matches("[a-zA-Z]+") && o2.matches("[a-zA-Z]+")) {
return o1.compareTo(o2);
}
Pattern p = Pattern.compile(REGEX);
Matcher m1 = p.matcher(o1);
Matcher m2 = p.matcher(o2);
List<String> list = new ArrayList<String>();
while (m1.find()) {
list.add(m1.group());
}
for (String string : list) {
o1.replaceFirst(string, leftPad(string, "0", maxLen));
}
list.clear();
while (m2.find()) {
list.add(m2.group());
}
for (String string : list) {
o2.replaceFirst(string, leftPad(string, "0", maxLen));
}
return o1.compareTo(o2);
}
}
public static String leftPad(String stringToPad, String padder, Integer size) {
final StringBuilder strb = new StringBuilder(size.intValue());
final StringCharacterIterator sci = new StringCharacterIterator(padder);
while (strb.length() < (size.intValue() - stringToPad.length())) {
for (char ch = sci.first(); ch != CharacterIterator.DONE; ch = sci.next()) {
if (strb.length() < (size.intValue() - stringToPad.length())) {
strb.insert(strb.length(), String.valueOf(ch));
}
}
}
return strb.append(stringToPad).toString();
}
【讨论】:
你应该实现一个比较器:
给定对象 O1 和对象 O2:
您首先尝试将它们转换为数字并比较数字。
如果 O1 是数字而 O2 不是,则认为 O2 大于 O1
如果 O1 不是数字而 O2 是数字,则认为 O1 大于 O1
如果两者都不是数字,则将它们作为字符串进行比较。
【讨论】:
你必须实现比较器。我假设你所有的数据都是字符串的形式。因此,默认情况下 "10" 在 "9" 之前。你需要自己实现 java.util.Comparator 来解决这个问题。
【讨论】:
首先您编写自己的Comparator,然后调用Collections.sort(List, Comparator)
【讨论】:
User952887 的答案很好,除了它仍然给出 0,01,1,10,11,2,21,3,4,5,...等(注意 10 在 1 之后和 2 之前)。查看以下链接以获取一个很棒的字母数字比较器,它将返回 0,1,2,3,4,5,10,11,21 http://sanjaal.com/java/tag/sample-alphanumeric-sorting/ 唯一的问题是它将返回 0,1,01-User952887 已修复.
【讨论】: