[英]How to sort Alphanumeric String
我對包含整數的字符串進行排序有問題。 如果我使用下面的代碼,我會得到這樣的排序: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());
}
});
這是一個關於如何執行此操作的獨立示例(未特別優化):
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
sInteger
s而不是整個String
s,因此導致數字比較而不是字典比較String
的字典比較(感謝MihaiC發現這個)您的解決方案在於Alphanum 算法,您可以像這樣實現
首先制作一個字母數字比較器,將字符串分成字符串或整數部分。
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 的靜態方法。
您需要實現自己的Comparator
來進行這種自定義排序。 默認的String.compareTo()
方法似乎在字符之前對數字進行排序。 當20some
0
與20some
中的s
進行3some
, 0
具有更高的排序優先級,因此整個單詞首先被排序。
您需要做的是:嘗試將字符串拆分為數字和字符部分。 這是一項艱巨的任務,因為這些String
可以包含許多這些部分(或者不是?)。 您可以使用像Alphanum
這樣的算法,Murtaza 已經向您展示過。
如果你想自己實現它,你可以檢查,數字部分在哪里結束。 然后使用Integer.parse()
將其解析為int
。 如果兩個String
中都存在int
部分,則比較它們,然后比較其余部分。 好吧,這可能不是最專業的解決方案,但作為初學者,您可能希望自己制作這些東西來學習它。
您不能使用默認的 String compareTo() 而是需要按照以下算法比較字符串。
重復這些步驟。
您可以使用正則表達式在一行中完成它的核心以提取數字部分:
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", ""));
}
});
這是一個有效的解決方案是 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]
如果您知道該模式始終是 NUMALPHA 或 ALPHANUM 並且 alpha 始終相同:
if(str1.length() != str2.length()){
return str1.length() - str2.length();
}
return str1.compareTo(str2);
如果您有字母數字字符串數組,則可以直接使用
Arrays.sort(Array_name)
然后打印:
for(String a : Array_name)
System.out.print(a);
如何使用比較器在 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 ]
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.