大聪明教你学Java

您所在的位置:网站首页 感叹号算特殊字符吗 大聪明教你学Java

大聪明教你学Java

2024-07-17 20:20| 来源: 网络整理| 查看: 265

前言

看到这个标题的时候估计有小伙伴会说:一个字符的 String.length() 肯定是1呗,那还能是多少… 但是事实真的是这样吗😉…

一探究竟

咱们先举个例子👇

/** * @description: Demo * @author: 庄霸.liziye * @create: 2022-02-11 09:23 **/ public class Demo { public static void main(String [] args){ String message = "我在人民广场吃着炸鸡"; System.out.println("message的长度是:" + message.length()); } }

各位小伙伴肯定一眼就能看出来结果是多少,没错~ 打印出来的长度是10💯那么我把上面的代码修改一下,大家再看看结果是多少呢👇

/** * @description: Demo * @author: 庄霸.liziye * @create: 2022-02-11 09:23 **/ public class Demo { public static void main(String [] args){ String message = "我在人民广场吃着炸鸡𝄞"; System.out.println("message的长度是:" + message.length()); } }

估计会有小伙伴脱口而出:这不就是多了一个符号嘛,结果肯定是11,这可难不倒我😄。那咱们一起来看看控制台打印出来的结果是多少~

在这里插入图片描述 控制台打印出来的结果居然是12 😮,也就是说 𝄞 字符的长度是2。这个结果就有点出乎意料了,我们在开发的时候肯定也计算过特殊字符(比如感叹号、问号、逗号等等)的长度,这些字符的长度都是1,那为什么 𝄞 的长度就变成了2呢… 各位稍安勿躁,我们一起来看看 String.length() 方法的源码👇

/** * Returns the length of this string. * The length is equal to the number of Unicode * code units in the string. * * @return the length of the sequence of characters represented by this * object. */ public int length() { return value.length; }

把注释翻译一下,大概的意思是:返回此字符串的长度,返回的长度等于字符串中的 unicode 代码单元数。那 “unicode 代码单元数” 又是什么呢?咱们接着往下看👇

在 Java 中有内码和外码的区分,简单来说内码就是 char 或 String 在内存里使用的编码方式;除内码外的编码方式都可以认为是外码(class 文件的编码也可以认为是外码)。而 Java 内码,也就是 unicode 中使用的是 UTF-16 编码方式。那么我们把上面的翻译再做进一步的解释就是:返回字符串的长度,这一长度等于字符串中的 UTF-16 的代码单元的数目。

代码单元(Code Unit)指的是一种转换格式(UTF)中最小的一个分隔,因此,一种转换格式只会包含整数个单元(UTF-X 中的数字 X 就是各自代码单元的位数)。UTF-16 的 16 指的就是最小为 16 位一个单元,即两字节为一个单元,UTF-16 可以包含一个单元和两个单元,对应即是两个字节和四个字节。我们操作 UTF-16 时就是以它的一个单元为基本单位的。UTF-16编码一个字符对 U+0000 - U+FFFF 范围内的字符采用2字节进行编码,而超过这个范围(大于 U+FFFF)的字符则采用四字节进行编码,前者是两字节也就是一个代码单元,后者一个字符是四字节也就是两个代码单元。说到这各位小伙伴肯定就明白了,因为 𝄞 字符的 Unicode 值大于 U+FFFF ,所以该字符在编码时用了四个字节,也就是两个代码单元,这也就是为什么 𝄞 字符的长度会是2。

讲到这或许有小伙伴会提出疑问:那我以后再用 String.length() 方法去计算字符串长度是不是就会出现问题了呢?其实完全不用担心,这种情况是极少遇到的,我们常用的字符(比如感叹号、问号、句号、逗号等等)Unicode 值都在 U+0000 - U+FFFF 范围内,我们是可以直接使用 String.length() 方法去计算其长度的,完全不用担心出现问题。即便我们真的遇到了这种极其特殊的字符,我们可以使用 String.codePointCount(int beginIndex, int endIndex) 方法去计算字符长度👇

/** * @description: Demo * @author: 庄霸.liziye * @create: 2022-02-11 09:23 **/ public class Demo { public static void main(String [] args){ String message = "𝄞"; System.out.println(message.length()); System.out.println(message.codePointCount(0,message.length())); } }

在这里插入图片描述 可能有些小伙伴没用过 String.codePointCount(int beginIndex, int endIndex) 方法,这里再简单说解释一下👇

UTF-16 是基于 Unicode 的不定长度的字符编码(不定长度是指,有些字符使用 2 个字节表示,有些字符使用 4 个字节表示)。UTF-16 的基本单位是 2 个字节,英文名叫 code unit,而真正能表示一个 Unicode 字符的数据(在 utf-16 中可能是 2 个字节也可能是 4 个字节)叫代码点,英文名叫 code point。 比如 “𝕆” 这个字符的 Unicode 码(或者叫代码点)是 U+1D546(超过了 上文中提到的编码范围),转换成 UTF-16 后就有两个代码单元,分别为 U+D835 和 U+DD46,此时使用 String.length() 去计算其长度,结果就是2,而如果使用 String.codePointCount(int beginIndex, int endIndex) ,那么结果就为 1 。

总结起来就是一句话:length() 方法计算的是代码单元,codePointCount() 计算的是代码点(即真正的字符数)。

参考:

https://juejin.cn/post/6844904036873814023#heading-0https://www.cjavapy.com/article/1692/ 小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇‍

希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●’◡’●)

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

你在被打击时,记起你的珍贵,抵抗恶意; 你在迷茫时,坚信你的珍贵,抛开蜚语; 爱你所爱 行你所行 听从你心 无问东西



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3