我需要按字母顺序对名称列表进行排序,为此我使用interfase comperator对名称进行排序
@Override
public int compareTo(ContactModel another) {
// TODO Auto-generated method stub
return getname().compareTo(another.getname());
}
假设这是我的名字数组
123vinish
23Sathya
24mahesh
Ranjith
Vipin
Bibin
Shine
Thomas
我需要按照一个序列来排序,其中带有数字的名称必须是最后的
Bibin
Ranjith
Shine
Thomas
Vipin
123Vinish
23Sathya
24mahesh
我们如何实现这个
答案 0 :(得分:8)
String.compareTo(String)
按字符的ascii值对字符串进行排序。你需要改变比较器。自定义比较器的示例:
List<String> al = new ArrayList<String>();
al.add("123vinish");
al.add("23Sathya");
al.add("24mahesh");
al.add("Ranjith");
al.add("Vipin");
al.add("Bibin");
al.add("Shine");
al.add("Thomas");
Comparator<String> nameComparator = new Comparator<String>()
{
@Override
public int compare(String value1, String value2)
{
if(Character.isDigit(value1.charAt(0))&&!Character.isDigit(value2.charAt(0)))
return 1;
if(Character.isDigit(value2.charAt(0))&&!Character.isDigit(value1.charAt(0)))
return -1;
return value1.compareTo(value2);
}
};
Collections.sort(al, nameComparator);
System.out.println(al);
输出: [Bibin, Ranjith, Shine, Thomas, Vipin, 123vinish, 23Sathya, 24mahesh]
如果要覆盖实现compareTo
接口的类中的Comparable<>
方法,则必须如下所示:
@Override
public int compareTo(ContactModel anotherValue)
{
if(Character.isDigit(this.getname().charAt(0))&&!Character.isDigit(anotherValue.getname().charAt(0)))
return 1;
if(Character.isDigit(anotherValue.getname().charAt(0))&&!Character.isDigit(this.getname().charAt(0)))
return -1;
return this.getname().compareTo(anotherValue.getname());
}
修改强>
如果你想要2a
之类的字符串出现在23
之类的字符串之前,那么你只需要遍历字符串中的每个字符。然后自定义比较器必须如下所示:
Comparator<String> nameComparator = new Comparator<String>()
{
@Override
public int compare(String value1, String value2)
{
for(int i = 0; i < Math.min(value1.length(), value2.length()); i++)
{
//value1 is digit and value2 is not
if(Character.isDigit(value1.charAt(i)) && !Character.isDigit(value2.charAt(i)))
return 1;
//value2 is digit and value1 is not
else if(Character.isDigit(value2.charAt(i)) && !Character.isDigit(value1.charAt(i)))
return -1;
//both are digits with different size
else if(Character.isDigit(value1.charAt(i)) && Character.isDigit(value2.charAt(i)) && Integer.valueOf(value1.charAt(i))!=Integer.valueOf(value2.charAt(i)))
return value1.compareTo(value2);
//both are no digits
else if(!Character.isDigit(value1.charAt(i)) && !Character.isDigit(value2.charAt(i)))
return value1.compareTo(value2);
//loop again if they are both digits with the same value
}
return value1.compareTo(value2);
}
};
编辑2:
我为您的问题创建了另一种解决方案。我在String类中复制了compareTo
方法的实现,并在比较时修改了数字的ascii值。此示例可用于ContactModel
类。
@Override
public int compareTo(ContactModel anotherValue) {
int len1 = this.getname().length();
int len2 = anotherValue.getname().length();
int lim = Math.min(len1, len2);
char v1[] = this.getname().toCharArray();
char v2[] = anotherValue.getname().toCharArray();
int k = 0;
while (k < lim) {
//Do the trick here! If char is a digit, add 75.
char c1 = Character.isDigit(v1[k]) ? ((char)(v1[k]+75)) : v1[k];
char c2 = Character.isDigit(v2[k]) ? ((char)(v2[k]+75)) : v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
答案 1 :(得分:0)
这个实现与你的第二个建议几乎相似
@Override
public int compareTo(ContactModel another) {
// TODO Auto-generated method stub
boolean lhsStartsWithDigit = Character.isDigit(getStartLetter().charAt(0));
boolean rhsStartsWithDigit= Character.isDigit(another.getStartLetter().charAt(0));
if((lhsStartsWithDigit && rhsStartsWithDigit) || (!lhsStartsWithDigit && ! rhsStartsWithDigit))
return getStartLetter().compareToIgnoreCase(another.getStartLetter());
else if(lhsStartsWithDigit)
return 1;
else
return -1;
}
我能遵循这个吗?