知识大全 跟你一起分析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中文问题集锦 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 解决java中文问题 针对
Java内存泄漏分析与解决方案 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Java内存泄漏是
Java多线程支持如何才能解决接口问题 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Java多
Java多线程如何解决关键字封锁问题 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Java多线
JavaSynDemo对象如何解决继承问题 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Jav
如何解决JavaME设备碎片问题 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一次编写随处运行
Weiss的java数据结构与问题解决 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! impor
关于JAVA的中文问题 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一主题关于JAVA的中文问
Javaweb解决常见编码出现的问题 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n
对JAVA的两个FTP包进行比较分析 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! ftp*;