在看Java從入門到精通的過程中遇到這樣一道習題:定義Student類,該類不實現Comparable接口,定義一個Comparator類比較兩個Student對象所在班級名稱和名字,班級名相同時用名字進行排序,使用TreeSet觀察排序結果。
這是我最初寫的程序和運行結果截圖
package javautil;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.Comparator;
class MyCompare implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
String strclass1 = o1.getClassid();
String strclass2 = o2.getClassid();
String strname1 = o1.getName();
String strname2 = o2.getName();
if((strclass1.compareTo(strclass2))!=0) {
return strclass1.compareTo(strclass2);
} else {
return strname1.compareTo(strname2);
}
}
}
public class shizhan20_2 {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>(new MyCompare());
ts.add(new Student("李四","3班"));
ts.add(new Student("張三","1班"));
ts.add(new Student("李四","1班"));
ts.add(new Student("張三","2班"));
ts.add(new Student("王五","1班"));
//System.out.println(ts);
Iterator<Student> ito = ts.iterator();
while(ito.hasNext()) {
Student s = ito.next();
System.out.println(s.getClassid()+","+s.getName());
}
}
}
很明顯,程序運行結果並不符合題目要求,他並沒有實現當班級名稱相同時對學生姓名進行排序的功能。接下來我開始Debug運行程序,發現程序並沒有漏洞,對錯誤原因也是百思不得其解,在多處寫了測試輸出後也看不出任何端倪,最後嘗試吧所有的名字改成拼音,下面是改成拼音以後的源程序以及運行結果截圖:
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>(new MyCompare());
ts.add(new Student("LiSi","3班"));
ts.add(new Student("ZhangSan","1班"));
ts.add(new Student("LiSi","1班"));
ts.add(new Student("ZhangSan","2班"));
ts.add(new Student("WangWu","1班"));
//System.out.println(ts);
Iterator<Student> ito = ts.iterator();
while(ito.hasNext()) {
Student s = ito.next();
System.out.println(s.getClassid()+","+s.getName());
}
運行結果是完全符合標準的,這樣就大概猜出了錯誤原因,就是compareTo( )方法在對字符串進行比較時,比較的是Unicode碼,並不能對漢字進行準確的排序,所以漢字比較時會出現比較混亂的結果。當然,Java自然有他的解決方式,通過上網搜和查API文檔,找到了一種解決辦法,java.text.Collator類中有一個getInstance(Locale desiredLocale) 方法可以解決對漢字排序的問題,這樣我們就需要重寫compare( )方法,修改後的最終完整代碼和運行結果截圖如下:
public class Student {
private String name=null;
private String classid=null;
public Student(String name,String classid) {
this.classid=classid;
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setClassid(String classid) {
this.classid = classid;
}
public String getClassid() {
return classid;
}
}
import java.util.Iterator;
import java.util.Locale;
import java.util.TreeSet;
import java.text.Collator;
import java.util.Comparator;
class MyCompare implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
String strclass1 = o1.getClassid();
String strclass2 = o2.getClassid();
String strname1 = o1.getName();
String strname2 = o2.getName();
if((strclass1.compareTo(strclass2))!=0) {
return strclass1.compareTo(strclass2);
} else {
Collator instance = Collator.getInstance(Locale.CHINA);
return instance.compare(strname1, strname2);
}
}
}
public class shizhan20_2 {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>(new MyCompare());
ts.add(new Student("李四","3班"));
ts.add(new Student("張三","1班"));
ts.add(new Student("李四","1班"));
ts.add(new Student("張三","2班"));
ts.add(new Student("王五","1班"));
//System.out.println(ts);
Iterator<Student> ito = ts.iterator();
while(ito.hasNext()) {
Student s = ito.next();
System.out.println(s.getClassid()+","+s.getName());
}
}
}