返回顶部
首页 > 资讯 > 精选 >JAVA中文比较问题的分析和解决是怎样的
  • 255
分享到

JAVA中文比较问题的分析和解决是怎样的

2023-06-03 03:06:01 255人浏览 泡泡鱼
摘要

这篇文章将为大家详细讲解有关JAVA中文比较问题的分析和解决是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 Java的中文问题由来已久,前不久需要做内存中的中文比较排序,对字符串进行

这篇文章将为大家详细讲解有关JAVA中文比较问题的分析和解决是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

 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;

 

  //取偏依位置

 

  //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

为什么Java在做汉字的CompareTo时比较会有问题呢?通过对compareTo源代码的分析发现,关键在于JDK的compareTo实现是直接使用Char来进行比较的:

  char c1 = v1[k];

  char c2 = v2[k];

可是当Java使用GB2312编码时,一个对汉字所获取到的Char值却是不规则的,即一个汉字在Java中作为一个char来处理(双字节字符)时,将这样的双字节字符进行强制转换成int类型时,所得到的不是包含了汉字编码顺序的中文内码。可以看一下一组测试数据可以看到其中奥妙:

字符

Char值

Byte[]值

按Byte[]合成的值

25105

[50:46]

[-5046]

29233

[80:82]

[-8082]

21271

[79:79]

[-7979]

20140

[66:87]

[-6687]

22825

[52:20]

[-5220]

23433

[80:78]

[-8078]

38376

[61:59]

[-6159]

A

65

[-65]

[65]

B

66

[-66]

[66]

C

67

[-67]

[67]

D

68

[-68]

[68]

按照中文顺序:“我”字应该在“爱”字后面,因此理论上来讲"我"字的Char值应该比“爱"字的char值要大。可是不知道为什么Java的汉字char(两个byte)->int类型的转换会发生很大偏差。而失去了汉字原本在GBK规范当中,按内码排列好的顺序。但从一个汉字拆分成2个字节的byte[]时,所得到的值并没有打乱GBK编码规定的顺序,因此得到解决问题的思路:将String进行GB2312编码后取得某个汉字获取其Char值时,将汉字拆分成2个字节byte[]再进行计算,从而得到正确的内码。

因此我自己写了下面这样几个函数,基本上解决了汉字比较的问题:

  函数包括三个,你可以随意放置到任何类当中作为辅助函数使用(Private Helper)。

n  public int compare(String s1, String s2) :主要工作是为比较做一些前期的编码工作可以说是系统的一个外壳。

n  public int chineseCompareTo(String s1, String s2):该函数则是中文字符串比较主体,其内部实现了比较的最基本逻辑,和JDK的compareTo所使用的逻辑是一样的。调用接口也一样。

n  public static int getCharCode(String s):该函数则负责将一个以字符串形式存在的字符转换成为int编码,儿不损失其位置信息。注意输入通常是:“我”或者“A”,如果输入更长的字符串,则改函数获得的是第一个字符的值。

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中文比较问题的分析和解决是怎样的就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: JAVA中文比较问题的分析和解决是怎样的

本文链接: https://lsjlt.com/news/232435.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JAVA中文比较问题的分析和解决是怎样的
    这篇文章将为大家详细讲解有关JAVA中文比较问题的分析和解决是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 Java的中文问题由来已久,前不久需要做内存中的中文比较排序,对字符串进行...
    99+
    2023-06-03
  • ActiveMQ问题分析和解决是怎样的
    ActiveMQ问题分析和解决是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1)KahaDb和AMQ Message Store两种持久方式如何选择?官方:From...
    99+
    2023-06-04
  • 怎样分析JSF的中文问题
    怎样分析JSF的中文问题,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。开始学习JSF的时候有遇上中文问题,看了一些文章后突然想起Struts也有中文问题,当时用...
    99+
    2023-06-03
  • 怎样解决Java/J2EE中文问题
    这篇文章给大家介绍怎样解决Java/J2EE中文问题,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。大部分程序员在编程中都遇到过Java中文问题,但是只要你知道了Java系统的中文问题原理,我们就可以对中文问题说拜拜。最...
    99+
    2023-06-17
  • JAVA常见中文问题的解决方案是怎样的呢
    JAVA常见中文问题的解决方案是怎样的呢,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。JAVA常见中文问题的解决方法以下解决方案是笔者在日常生活中遇到的,希望能...
    99+
    2023-06-03
  • 解决Java包装类比较时遇到的问题
    前言本文主要给大家介绍了关于Java包装类在比较时遇到的一些问题的解决方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。例1: Integer a = 1; Integer b = 2; Integer c = 3...
    99+
    2023-05-31
    java 包装类比较 ava
  • Java中对象比较的示例分析
    这篇文章主要介绍了Java中对象比较的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。元素比较基本类型的比较在Java中,基本类型的对象可以直接比较大小public&n...
    99+
    2023-06-29
  • Oracle分区数据问题的分析和修复是怎样的
    Oracle分区数据问题的分析和修复是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 今天根据同事的反馈,处理了一个分区表的问题,也让...
    99+
    2024-04-02
  • Java中文问题的示例分析
    这篇文章将为大家详细讲解有关Java中文问题的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。我来说一下tomcat如何实现JSP的你就明白了。预备知识: 1.字节和unicode  Java内核是...
    99+
    2023-06-03
  • 分析和解决java.lang.OutOfMemoryError: Java heap space问题
    这里写目录标题 问题场景问题分析与解决1.优化项目代码2.提升Java heap size3.JVM参数配置配置参考堆区参数配置说明非堆区参数配置说明 问题场景 最近客户反馈在生...
    99+
    2023-10-24
    java jvm 开发语言 优化 内存
  • CentOS系统中英文问题解决方案是怎样的
    今天就跟大家聊聊有关CentOS系统中英文问题解决方案是怎样的,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在CentOS系统中,文字一直是困扰我们的一个大问题。由于CentOS系统...
    99+
    2023-06-16
  • 解析Java和IDEA中的文件打包问题
    问题:想在IDEA中引用相对路径,但是找不到文件。 项目目录结构 当前项目的路径为:D:\source\java\test\ 项目结构如下 当前路径 面对无法使用相对路径找到资源文...
    99+
    2024-04-02
  • 分析和解决golang中interface转换的问题
    随着人们对于Golang语言的应用越来越深入,对于其中的一些特性和技术也有了更深入的认识。其中,golang中的interface是一项非常重要且强大的特性,具有很大的灵活性和可扩展性。在实际应用中,我们不可避免地需要使用interface...
    99+
    2023-05-14
  • 分析和解决golang文件乱码问题
    作为一门新兴的编程语言,Golang在近几年的快速发展中不断吸引着越来越多的程序员。然而,在使用Golang编写文件时,可能会遇到文件乱码的问题,这给程序员的开发带来了很多麻烦。本文将从以下方面对Golang文件乱码问题进行深入探讨。一、G...
    99+
    2023-05-14
  • MySQL备份失败的问题分析和处理是怎样的
    本篇文章为大家展示了MySQL备份失败的问题分析和处理是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。今天和同事一起处理了一个奇怪的MySQL空间异常问题,从...
    99+
    2024-04-02
  • SecureCRT中文显示乱码问题的解决方法是怎样的
    本篇文章为大家展示了SecureCRT中文显示乱码问题的解决方法是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 修改远程linux机器的配置 vim /etc/sysconfig/i18n ...
    99+
    2023-06-13
  • 容器开发技术:Java和JavaScript的比较分析
    随着云计算的发展,容器技术越来越成为开发人员的选择。在容器技术中,Java和JavaScript是两种最常用的语言。本文将比较Java和JavaScript在容器开发技术中的优缺点,帮助开发人员选择合适的语言。 Java和JavaScri...
    99+
    2023-08-16
    javascript 开发技术 容器
  • Java Iterator 和 Iterable 的深入比较:优缺点分析
    概念差异: Iterator: Iterator是一个接口,代表一个从集合中获取值的迭代器。它提供了MoveNext()、Current()和Reset()等方法,允许你遍历集合中的元素,并对当前元素进行操作。 Iterable:...
    99+
    2024-02-14
    Java, Iterator, Iterable, Collection, 遍历, 性能, 迭代器, 可迭代
  • java中关于对象的实例比较分析
    本篇内容主要讲解“java中关于对象的实例比较分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java中关于对象的实例比较分析”吧!同类型对象的比较三个维度去比较同一性相等性相似性样例引入想象...
    99+
    2023-06-26
  • Java中对HashMap的深度分析与比较(转)
    Java中对HashMap的深度分析与比较(转)[@more@]在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键。由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题。找遍了大大小小的...
    99+
    2023-06-03
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作