java的中文问题由来已久,前不久笔者需要做内存中的中文比较排序,对字符串进行gbk或者gb2312编码以后,使用string.compareto方法仍然不能得到正确结果。因此,怀着怀疑的态度,对jdk中string类的源代码做了一翻探究。(作者使用jdk为1.3.1版本)
以下是string.java中compareto的源代码,请注意其中的注释:
public class string
{
…
public int compareto(string anotherstring) {
int len1 = count;
int len2 = anotherstring.count;
//n为两个字符串长度的最小者
int n = math.min(len1, len2);
//获取字符数组
char v1[] = value;
char v2[] = anotherstring.value;
//取偏依位置
/** the offset is the first index of the storage that is used. */
//offset 是第一个存储索引
int i = offset;
int j = anotherstring.offset;
//如果i == j
//这里可能是判断取同一内存中两个字符串的情景。。。
// a <-- <----
// b s1
// c <--
// d s2
// e
// f
// g <----------
// 可能这种情况 i = j
if (i == j) {
int k = i;
int lim = n + i;
while (k < lim)
{
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) file://直到找到一个不相等的字符,返回c1 - c2
return c1 - c2;
k++;
}
} else {
while (n-- != 0) file://直到两个字符串长度记数为0
{
char c1 = v1[i++]; file://分别取字符
char c2 = v2[j++];
if (c1 != c2) { //发现不相等,立即返回c1 - c2;
return c1 - c2;
}
}
}
return len1 - len2;
//最后这里可能出现的情况是: 两个字符串比较完之后还没有得到结果。相等的情况
}
…
}//end of class string
private static string __encode__ = "gbk"; file://一定要是gbk
private static string __server_encode__ = "gb2312"; file://服务器上的缺省编码
/*
比较两字符串
*/
public int compare(string s1, string s2)
{
string m_s1 = null, m_s2 = null;
try
{
//先将两字符串编码成gbk
m_s1 = new string ( s1.getbytes(__server_encode__), __encode__);
m_s2 = new string ( s2.getbytes(__server_encode__), __encode__);
}
catch( exception ex)
{
return s1.compareto(s2);
}
int res = chinesecompareto(m_s1, m_s2);
system.out.println("比较:" + s1 + " " + s2 + "==== result: " + res);
return res;
}
//获取一个汉字/字母的char值
public static int getcharcode(string s)
{
if (s==null && s.equals(“”)) return -1; file://保护代码
byte [] b = s.getbytes();
int value = 0;
//保证取第一个字符(汉字或者英文)
for (int i = 0; i < b.length && i <= 2; i ++)
{
value = value * 100 + b[i];
}
return value;
}
//比较两个字符串
public int chinesecompareto(string s1, string s2)
{
int len1 = s1.length();
int len2 = s2.length();
int n = math.min(len1, len2);
for (int i = 0; i < n; i ++)
{
int s1_code = getcharcode(s1.charat(i) + "");
int s2_code = getcharcode(s2.charat(i) + "");
if (s1_code != s2_code) return s1_code - s2_code;
}
return len1 - len2;
}
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器