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


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

}

}

}

时间: 2024-10-12 21:09:20

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

String类中的常用方法

String类 一.转换成String方法 1.public String(); 空参构造 初始化一个新创建的 String 对象,使其表示一个空字符序列 2.public String(byte[] bytes); 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String 将97,97.99转成ascll码表对应的字符; 3.public String(byte[] bytes,int index,int length); 分配一个新的 String,使其表示字符数组参数

java 集合框架(TreeSet操作,自动对数据进行排序,重写CompareTo方法)

/*TreeSet * treeSet存入数据后自动调用元素的compareTo(Object obj) 方法,自动对数据进行排序 * 所以输出的数据是经过排序的数据 * 注:compareTo方法返回值有:负数,零,正数.分别表示小于,等于,大于 * 对于存入自定义的对象元素,要重写元素的compareTo(Object obj)方法 * 元素定义时,需要实现Comparable接口 * */ 1 import java.util.Iterator; 2 import java.util.Tr

java中String类中的replace方法

package stringTest; public class StringDemo2 { public static void main(String[] args) { String s = "acvbb"; String s1 = new String("acvbb"); String s2 = s.replace("a", "X"); String s3 = s1.replace("a", &qu

String类中intern方法的原理分析

一,前言 ? 昨天简单整理了JVM内存分配和String类常用方法,遇到了String中的intern()方法.本来想一并总结起来,但是intern方法还涉及到JDK版本的问题,内容也相对较多,所以今天就弥补昨天缺失的知识点. 二,String.intern() ? 先来看下网上流行的关于intern()方法的示例代码: public static void main(String[] args) { String s = new String("1"); s.intern(); St

java的Object类中hashCode()和equals()方法-----转载

JAVA代码:    public static void main(String[] args)    {        Object obj1 = new Object();        Object obj2= new Object();        Object obj3 = obj2;        System.out.println("obj1==obj2 ?"+obj1.equals(obj2));        System.out.println("o

php面向对象类中常用的魔术方法

php面向对象类中常用的魔术方法 1.__construct():构造方法,当类被实例化new $class时被自动调用的方法,在类的继承中可以继承与覆盖该方法,例: //__construct() class construct{ public function __construct(){ $this->var = "this is var"; } } class con2 extends construct{ public function __construct(){ $

【Android进阶】为什么要创建Activity基类以及Activity基类中一般有哪些方法

现在也算是刚刚基本完成了自己的第一个商业项目,在开发的过程中,参考了不少人的代码风格,然而随着工作经验的积累,终于开始慢慢的了解到抽象思想在面向对象编程中的重要性,这一篇简单的介绍一下我的一点收获. 首先,在现在的项目中使用的主要是afinal框架,而且这个框架确实比较不错,省去了不少工作量,在编写Activity的过程中,基本都是直接继承自FinalActivity类,这样可以使用这个类给我们封装好的不少的方法,但是随着项目慢慢推进,这种直接继承框架类的一些缺点也开始慢慢的显现出来.最主要的就

String类中的常用方法_判断

字符串判断:1,字符串石佛包含某个字符串.boolean contains(str); 特殊之处:indexOf(String str),如果返回的值是-1,那么就表示不包含这个字符串 也可以实现判断. 2,字符串是否有内容.boolean isEmpty() 字符串为空时返回true 3,字符串是否以指定内容开头  boolean startsWith(String str) boolean startsWith(String str,int fromindex); 4,字符串是否以指定内容结

String类原理分析及部分方法

//String类原理分析及部分方法 //http://www.cnblogs.com/vamei/archive/2013/04/08/3000914.html //http://www.cnblogs.com/YSO1983/archive/2009/12/07/1618564.html //String类包含在java.lang包中,这个包在java的时候就自动import //String类是唯一一个不需要new关键词来创建对象的类. public class Test{ public