知识大全 跟你一起分析JAVA中文比较问题的解决

Posted

篇首语:明明你一个人可以活的很开心的,偏偏非要学别人谈恋爱……本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 跟你一起分析JAVA中文比较问题的解决相关的知识,希望对你有一定的参考价值。

跟你一起分析JAVA中文比较问题的解决  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  Java的中文问题由来已久 前不久笔者需要做内存中的中文比较排序 对字符串进行GBK或者GB 编码以后 使用pareTo方法仍然不能得到正确结果 因此 怀着怀疑的态度 对JDK中String类的源代码做了一翻探究 (作者使用JDK为 版本)    以下是String java中pareTo的源代码 请注意其中的注释     public class String    …  public int pareTo(String anotherString)   int len = count;  int len = unt;  //n为两个字符串长度的最小者  int n = Math min(len len );  //获取字符数组  char v [] = value;  char v [] = 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  s    |  // C  <    |  // D      s   // E      |  // F      |  // G  <   // 可能这种情况 i = j  if (i == j)   int k = i;  int lim = n + i;    while (k < lim)    char c = v [k];  char c = v [k];  if (c != c ) file://直到找到一个不相等的字符 返回c c   return c c ;  k++;     else   while (n != )  file://直到两个字符串长度记数为     char c = v [i++]; file://分别取字符  char c = v [j++];  if (c != c )   //发现不相等 立即返回c c ;  return c c ;        return len len ;  //最后这里可能出现的情况是: 两个字符串比较完之后还没有得到结果 相等的情况    …  //end of class String c ) file://直到找到一个不相等的字符 返回c c               return c c ;           k++;          else       while (n != ) file://直到两个字符串长度记数为                   char c = v [i++]; file://分别取字符           char c = v [j++];           if (c != c )  //发现不相等 立即返回c c ;              return c c ;                         return len len ; //最后这里可能出现的情况是: 两个字符串比较完之后还没有得到结果 相等的情况  …//end of class String    为什么Java在做汉字的CompareTo时比较会有问题呢?通过对pareTo源代码的分析发现 关键在于JDK的pareTo实现是直接使用Char来进行比较的     char c = v [k];    char c = v [k];    可是当Java使用GB 编码时 一个对汉字所获取到的Char值却是不规则的 即一个汉字在Java中作为一个char来处理(双字节字符)时 将这样的双字节字符进行强制转换成int类型时 所得到的不是包含了汉字编码顺序的中文内码 可以看一下一组测试数据可以看到其中奥妙     字符  Char值  Byte[]值  按Byte[]合成的值    我     [ : ]  [ ]    爱     [ : ]  [ ]    北     [ : ]  [ ]    京     [ : ]  [ ]    天     [ : ]  [ ]    安     [ : ]  [ ]    门     [ : ]  [ ]    A     [ ]  [ ]    B     [ ]  [ ]    C     [ ]  [ ]    D     [ ]  [ ]    按照中文顺序 我 字应该在 爱 字后面 因此理论上来讲 我 字的Char值应该比 爱 字的char值要大 可是不知道为什么Java的汉字char(两个byte) >int类型的转换会发生很大偏差 而失去了汉字原本在GBK规范当中 按内码排列好的顺序 但从一个汉字拆分成 个字节的byte[]时 所得到的值并没有打乱GBK编码规定的顺序 因此得到解决问题的思路 将String进行GB 编码后取得某个汉字获取其Char值时 将汉字拆分成 个字节byte[]再进行计算 从而得到正确的内码     因此我自己写了下面这样几个函数 基本上解决了汉字比较的问题     函数包括三个 你可以随意放置到任何类当中作为辅助函数使用(Private Helper)     n public int pare(String s String s ) 主要工作是为比较做一些前期的编码工作可以说是系统的一个外壳     n public int chineseCompareTo(String s String s ) 该函数则是中文字符串比较主体 其内部实现了比较的最基本逻辑 和JDK的pareTo所使用的逻辑是一样的 调用接口也一样     n public static int getCharCode(String s) 该函数则负责将一个以字符串形式存在的字符转换成为int编码 儿不损失其位置信息 注意输入通常是 我 或者 A 如果输入更长的字符串 则改函数获得的是第一个字符的值     private static String __ENCODE__ = GBK ; file://一定要是GBKprivate static String __SERVER_ENCODE__ = GB ; file://服务器上的缺省编码/*比较两字符串*/    public int pare(String s String s )           String m_s = null m_s = null;       try                  //先将两字符串编码成GBK           m_s = new String ( s getBytes(__SERVER_ENCODE__) __ENCODE__);           m_s = new String ( s getBytes(__SERVER_ENCODE__) __ENCODE__);              catch( Exception ex)                  return pareTo(s );              int res = chineseCompareTo(m_s m_s );        System out println( 比较 + s + | + s + ==== Result: + res);       return res;    //获取一个汉字/字母的Char值    public static int getCharCode(String s)           if (s==null && s equals( )) return ; file://保护代码byte [] b = s getBytes();       int value = ;       //保证取第一个字符(汉字或者英文)       for (int i = ; 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;        可见,对系统源代码的解剖,能让我们在迷惑之余同样有机会窥探系统内部运作的奥妙。.wiNGwit不过让人非常费解的是,Java内部的某些类书写风格非常不好,同时存在一些Bug。不过这也许是笔者个人感受。偶有所获,愿与大家共同分享,其中疏漏之处望不吝赐教。 cha138/Article/program/Java/JSP/201311/19557

相关参考

知识大全 Java 中文问题 集锦

Java中文问题集锦  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  解决java中文问题  针对

知识大全 Java内存泄漏分析与解决方案

Java内存泄漏分析与解决方案  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java内存泄漏是

知识大全 Java多线程支持如何才能解决接口问题

Java多线程支持如何才能解决接口问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java多

知识大全 Java多线程如何解决关键字封锁问题

Java多线程如何解决关键字封锁问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java多线

知识大全 Java SynDemo对象如何解决继承问题

JavaSynDemo对象如何解决继承问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Jav

知识大全 如何解决Java ME设备碎片问题

如何解决JavaME设备碎片问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一次编写随处运行

知识大全 Weiss的java数据结构与问题解决

Weiss的java数据结构与问题解决  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  impor

知识大全 关于JAVA的中文问题

关于JAVA的中文问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一主题关于JAVA的中文问

知识大全 Java web解决常见编码出现的问题

Javaweb解决常见编码出现的问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n

知识大全 对JAVA的两个FTP包进行比较分析

对JAVA的两个FTP包进行比较分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ftp*;