String类中自动重写compareTo( )方法对汉字的比较

来源:互联网 发布:java中的io和nio 编辑:程序博客网 时间:2024/06/05 19:46
 String类中自动重写compareTo( )方法对汉字的比较
2016-09-24 09:23:29
转载自:http://a001807.blog.51cto.com/9804844/1856006
1
<br>

在看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());

}

}

}

 

wKioL1fl1LmwGmoqAAApjjwwibk894.png-wh_50 

 

 

 

 

 

 

 

 

 

 

很明显,程序运行结果并不符合题目要求,他并没有实现当班级名称相同时对学生姓名进行排序的功能。接下来我开始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());

}

wKiom1fl1OnyIpe8AAAoapcYZ8w794.png-wh_50}

 

 

 

 

 

 

 

 

 

 

 

运行结果是完全符合标准的,这样就大概猜出了错误原因,就是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(strname1strname2);

}

}

}

 

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());

}

}

}

wKioL1fl1Q_jtyrLAAAoabmRQbg695.png-wh_50 

 

 

 

 

 

 

 

 

 

 

 


本文出自 “java” 博客,请务必保留此出处http://a001807.blog.51cto.com/9804844/1856006


附:

java中的compareto方法,返回参与比较的前后两个字符串的asc码的差值,看下面一组代码
String a="a",b="b";
System.out.println(a.compareto.b);
则输出-1;
若a="a",b="a"则输出0;
若a="b",b="a"则输出1;
 
单个字符这样比较,若字符串比较长呢??
若a="ab",b="b",则输出-1;
若a="abcdef",b="b"则输出-1;
也就是说,如果两个字符串首字母不同,则该方法返回首字母的asc码的差值;
 
如果首字母相同呢??
若a="ab",b="a",输出1;
若a="abcdef",b="a"输出5;
若a="abcdef",b="abc"输出3;
若a="abcdef",b="ace"输出-1;
即参与比较的两个字符串如果首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的asc码差值,如果两个字符串不一样长,可以参与比较的字符又完全一样,则返回两个字符串的长度差值

原创粉丝点击