• Java基本的程序结构设计 字符类型


    char类型

    char是2个字节,和short一样。

    char用单引号来表示。

    char可以通过数字来表示,也可以通过字母来表示,也可以通过unicode编码单元来表示,特殊字符还可以通过+字符来表示。如下:

    1. package com.zjf;
    2.  
    3. public class Test {
    4.  
    5.    public static void main(String[] args) {
    6.  
    7.       char c1 = 'A';
    8.       System.out.println(c1);
    9.       char c2 = 65;
    10.       System.out.println(c2);
    11.       char c3 = 'u0041';
    12.       System.out.println(c3);
    13.       char c4 = ' ';
    14.       System.out.println(c4);
    15.    }
    16. }

    输出:

    unicode编码

    要想理解java 的char类型,必须要先了解unicode编码:

    Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。

    Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。目前的Unicode字符分为17组编排,0x0000 至 0xFFFF,每组称为平面(Plane),而每平面拥有65536个码位,共1114112个。然而目前只用了少数平面。Unicode 用数字-0x000000 -0x10FFFF来映射这些字符,其实原来uncode编码是0x0000 至 0xFFFF,也就是说2个字节,16位,后来不够了,又加了8位,也就是1个字节,不知道为什么,加的这一个字节本来可以使用ox00-oxFF中变化的,也就是说256种,不知道为什么只用了17种。也就是0x00-0x10。不过这17中已经只用了很少一部分,如果要有256中,估计要把外星人语言加进来才行了。

    Unicode是编码规范,UTF-8UTF-16UTF-32都是将数字转换到程序数据的编码方案。UTF是"UCS Transformation Format"的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。对于字符'字',Unicode编码使用数字23383,也就是0x5b57。不论是使用UTF-8UTF-16UTF-32哪种编码,最终都要生成数字23383,只是采用不同的规则。

    UTF-8:

    UTF-8以字节为单位对Unicode进行编码。从Unicode到UTF-8的编码方式如 下:
    Unicode编码(16进制) ║ UTF-8 字节流(二进制) 

    • 000000 - 00007F ║ 0xxxxxxx 
    • 000080 - 0007FF ║ 110xxxxx 10xxxxxx
    • 000800 - 00FFFF ║ 1110xxxx 10xxxxxx 10xxxxxx 
    • 010000 - 10FFFF ║ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

    UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数 字。Unicode的最大码位0x10FFFF也只有21位。

    对于字符'字',Unicode编码使用数字23383。使用UTF-8进行存储的时候,是oxE5AD97,三个字节。

    它的二进制是:111001011010110110010111,可以按照上面的1110xxxx 10xxxxxx 10xxxxxx的规则进行拆分,拆分后把所有的x排成一行,就是:

    0101101101010111

    转换成10进制就是数字23383。

    UTF-16

    UTF-16编码以16位无符号整数为单位。我们把Unicode编码记作U。编码规则如下:
    如果U<0x10000,U的UTF-16编码就是U对应的16位无符号整数(为书写简 便,下文将16位无符号整数记作WORD)。 
    如果U≥0x10000,我们先计算U'=U-0x10000,然后将U'写成二进制形 式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16编码(二进制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx。 

    对于字符字符'字',使用数字23383,也就是ox5b57。

    也就是你说UTF-16的大部分字符都是2个字节(16位),生僻字可能是4个字节(2个16位)。

    也就是说16位是一个单元,并不是说每个字符都是16位。

    java中的char是采用的UTF-16编码来描述一个代码单元的。

    UTF-16有Big Endian Little Endian两种,代表在内存中,是高地址在前还是低地址在前,java采用的是Big Endian。对于字符字符'字',在内存中是101101101010111。如果是Little Endian,应该是反过来。

     

    字符串型

    从概念上讲,java的字符型就是unicode字符序列。

    不可变:

    一旦定义了一个字符串,就没有方法修改它。java没有提供修改字符串的方法,对于C程序来说,字符串相当于是个数组,你可以改变任何一个下标的值。但是Java不可以。

    如果要对java字符串修改下标,只能新建一个字符串,然后通过substring和拼接来实现,这样一定程度上效率很低。

    但是java设计者认为字符串修改操作很少,对于字符串的操作,大多是比较,和合并等操作。所以java设计者将字符串设置为不可变,然后实现了共享。

    没有字符串是可变的,就不能实现共享:

    可以想象将字符串放在一个公共的池中,字符串变量指向池中的值,如果复制一个字符串,源字符串和复制的字符串共享相同的位置。

    java设计者认为共享带来的高效率远远胜过可修改的字符串。

    检测相等:

    因为不可变,所以不能用==,只能用equals。

    因为String是对象,对于对象的比较,==在java中是用来比较对象指向的堆中的位置是否相同。

    虽然如此,如果我们用=比较对象指向的堆中的位置是否一样,也是不可以。

    1. package com.zjf;
    2.  
    3. public class Test {
    4.  
    5.    public static void main(String[] args) {
    6.  
    7.       String s1 = "zhang";
    8.       String s2 = "zhang";
    9.       System.out.println(s1 == s2);
    10.    }
    11. }

    结果为true。对我们来说,并没有做s1=s2的操作,结果却是true,这不是我们想要的结果。虽然说Sting a = b;那么用a == b是可以的,但是如果没有a=b,也可以a==b,这样对我们来说,会有不可预知的结果。

    那么如果我们想用=来比较两个字符串的内容是否一致呢?也不行。

    1. package com.zjf;
    2.  
    3. public class Test {
    4.  
    5.    public static void main(String[] args) {
    6.  
    7.       String s1 = "zhang";
    8.       String s2 = "zhangjianfeng".substring(0, 5);
    9.       System.out.println(s1);
    10.       System.out.println(s2);
    11.       System.out.println(s1 == s2);
    12.    }
    13. }

    结果为:

    zhang

    zhang

    false

     

    两个字符串都是zhang,使用=却没有比较成功。

    原因是因为java虚拟机只对字符串常量进行共享,对于+和substring等操作产生的结果,是不会共享的。

    使用==进行字符串比较,程序会出现bug,而且这种bug在一定程度上是随机的。不要使用。

    代码点和代码单元

    Java字符串由char序列组成,char是采用UTF-16编码表示Unicod代码点的代码单元。

    代码点就是我们生活中面对的一个字,因为UTF-16的存储方式,对于某些代码点需要32位,也就是说两个代码单元来存储,在java中,一个char是一个代码单元。

    这样就会造成一些误解。

    首先,length方法返回的是代码单元的数量。而不是代码点的数量。

    其次,charAt方法获取的是代码单元,不是代码点。如果想获取代码点,string提供的有codepoint方法,

    如下代码:

    作者说,避免使用char,因为这太低级了。其实,虽然很少见到这些特殊字符,使用char的场景还是要慎重。

    构建字符串:

    使用较短的字符串构建字符串:

    • StringBuilder
    • StringBuffer 线程安全

    包引入问题

    像Sting,Integer,StringBuilder这种包,位于java.lang目录下,不需要import引入,也能识别。

  • 相关阅读:
    Bootstrap3.0学习第八轮
    内存管理相关的信息
    SVN merge
    Asp.Net MVC 3
    formValidator
    jquery 分页控件2
    从零开始学C++之STL(四):算法简介、7种算法分类
    (Java实现) 过河卒
    (Java实现) N皇后问题
    (Java实现) N皇后问题
  • 原文地址:https://www.cnblogs.com/xiaolang8762400/p/7041087.html
Copyright © 2020-2023  润新知