1、u刘刚刘刚 刘伟刘伟 编著编著 如果将编程比作建楼房,那么字符串就相当于一块如果将编程比作建楼房,那么字符串就相当于一块砖,没有了基本类型,楼还是可以盖起来,只是会稍微砖,没有了基本类型,楼还是可以盖起来,只是会稍微费力些。但是如果没有了字符串,这栋楼或许就真的无费力些。但是如果没有了字符串,这栋楼或许就真的无法建造了。法建造了。字符串是重要的类型,在目前许多开发语言中,它字符串是重要的类型,在目前许多开发语言中,它的身影随处可见。目前流行的跨语言、跨平台的开发中,的身影随处可见。目前流行的跨语言、跨平台的开发中,字符串扮演了重要的角色,就其重要性而言,再怎么称字符串扮演了重要的角色,就其重要
2、性而言,再怎么称赞也不为过。赞也不为过。4.1 String 4.1 String 类及其常用类及其常用 API API 字符串由一连串的字符组成,在字符串由一连串的字符组成,在 Java Java 中使用双引中使用双引号号包裹表示,它可以是一个字符,也可以是一个字符包裹表示,它可以是一个字符,也可以是一个字符序列或者由多个字符序列组成序列或者由多个字符序列组成。Java Java 核心的类库中定核心的类库中定义了义了 String String 类用于字符串的常用操作,同时也定义了类用于字符串的常用操作,同时也定义了 StringBufferStringBuffer 和和 StringBui
3、lderStringBuilder 类用于字符串的复类用于字符串的复杂操作杂操作。想要使用字符串,首先需要对其进行初始化,字符想要使用字符串,首先需要对其进行初始化,字符串的初始化可以使用字面量(字符串常量)直接定义,串的初始化可以使用字面量(字符串常量)直接定义,或者使用构造函数进行初始化或者使用构造函数进行初始化。1 1字面量初始化字面量初始化 String String strstr=adcadc;字面量是指一个固定的值,此处字面量是指一个固定的值,此处“abc”“abc”就是字面量就是字面量。因为字符串常量池存在的原因,此处可以通过简化初始因为字符串常量池存在的原因,此处可以通过简化初
4、始化的方式,直接将字面量赋值给一个字符串对象化的方式,直接将字面量赋值给一个字符串对象。2 2使用构造函数初始化字符串使用构造函数初始化字符串 String str_1=new String();/String str_1=new String();/无参数构造方法无参数构造方法 String str_2=new String(String str_2=new String(adcadc);/);/使用字符串作为参数使用字符串作为参数的构造方法的构造方法 String str_3=new String(new char3);/String str_3=new String(new char3)
5、;/使用字符数使用字符数组作为参数的构造方法组作为参数的构造方法 Java Java 中中 String String 类中定义了这类中定义了这 3 3 种基本的初始种基本的初始化构造函数,从第化构造函数,从第 3 3 种使用一个字符数组初始化的构种使用一个字符数组初始化的构造函数中不难发现,其实字符串就是一组字符造函数中不难发现,其实字符串就是一组字符。字符串字符串初始化的实现如案例初始化的实现如案例 4-1 4-1 所示所示。运行结果如图运行结果如图 4-1 4-1 所示。所示。图图 4-1 运行结果运行结果 由运行结果可知,字符串的无参数构造方法是将一由运行结果可知,字符串的无参数构造方
6、法是将一个空字符串赋值给了字符串对象,而空字符串并不等于个空字符串赋值给了字符串对象,而空字符串并不等于nullnull,在开发的过程中千万不要将这两者混淆了。,在开发的过程中千万不要将这两者混淆了。4.1.1 4.1.1 字符串常量池字符串常量池 常量是指在程序运行过程中不会改变的量常量是指在程序运行过程中不会改变的量,一般从字,一般从字面形式就可以进行判断,也被称为字面量面形式就可以进行判断,也被称为字面量。如果将池的概。如果将池的概念简单地理解为池塘,字符串常量池则是拥有很多字符串念简单地理解为池塘,字符串常量池则是拥有很多字符串常量的池塘,包含着诸如常量的池塘,包含着诸如“a”“BGK
7、”“123”“a”“BGK”“123”等字符串等字符串常量。常量。JavaJava虚拟机在执行字节码时,把字节码解释成具体虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令来执行,这种执行方式让它有了极大平台上的机器指令来执行,这种执行方式让它有了极大的自由来提升性能,字符串常量池就是用来减少字符串的自由来提升性能,字符串常量池就是用来减少字符串对象创建分配过程中对时间和空间的消耗。字符串常量对象创建分配过程中对时间和空间的消耗。字符串常量池是在池是在 Java Java 虚拟机中单独开辟的一块特殊内存,这块虚拟机中单独开辟的一块特殊内存,这块内存用于存放程序在运行中使用到的字符串常量。
8、每当内存用于存放程序在运行中使用到的字符串常量。每当程序需要创建字符串常量的时候,程序需要创建字符串常量的时候,Java Java 虚拟机会先从虚拟机会先从字符串常量池中去找,如果找到了,则会返回池中的实字符串常量池中去找,如果找到了,则会返回池中的实例引用,如果找不到则会实例化一个字符串并将其放入例引用,如果找不到则会实例化一个字符串并将其放入常量池中。常量池中。字符串常量池这个概念太过于抽象,结合案例字符串常量池这个概念太过于抽象,结合案例 4-2 4-2 会更便于我们理解。会更便于我们理解。运行结果如图运行结果如图 4-2 4-2 所示。所示。图图 4-2 运行结果运行结果 从运行结果可
9、以看出,创建一个空从运行结果可以看出,创建一个空的字符串和只声明一个字符串消耗的时的字符串和只声明一个字符串消耗的时间几乎一样,而使用常量池的方式几乎间几乎一样,而使用常量池的方式几乎不需要耗费创建的时间,由此可见字符不需要耗费创建的时间,由此可见字符串常量池的存在意义。串常量池的存在意义。4.1.2 4.1.2 字符串常用字符串常用 API API 字符串操作是计算机程序设计中最常见的行为,字符字符串操作是计算机程序设计中最常见的行为,字符串对应的操作方法也是很丰富的,常用的方法如表串对应的操作方法也是很丰富的,常用的方法如表 4-1 4-1所所示。示。表表 4-1 String 类的常用方
10、法类的常用方法续表续表 String String 类的常用方法很多,但可以总体归为类的常用方法很多,但可以总体归为 4 4 类:类:字符串查询操作、字符串修改操作、字符串分割操作以字符串查询操作、字符串修改操作、字符串分割操作以及字符串比较操作。及字符串比较操作。在学习这些功能性的方法之前,先通过案例在学习这些功能性的方法之前,先通过案例 4-3 4-3 了了解字符串的通用功能性方法,例如长度和是否为空。解字符串的通用功能性方法,例如长度和是否为空。运行结果如图运行结果如图 4-3 4-3 所示。所示。图图 4-3 运行结果运行结果 在案例中不难发现,在案例中不难发现,isEmpty isE
11、mpty 对于为对于为 null null 的字符串的字符串是没有返回的,是没有返回的,length length 亦是如此,亦是如此,isEmpty isEmpty 仅当仅当 length length为为 0 0 时返回时返回 true true,否则返回,否则返回 false false。而。而 length length 则是对则是对字符个数的统计,空格和标点也被当作一个字符,且索引从字符个数的统计,空格和标点也被当作一个字符,且索引从 0 0 开始计算。开始计算。1 1字符串查询操作字符串查询操作 在互联网快速发展的今天,网购已经成为人们生活在互联网快速发展的今天,网购已经成为人们生
12、活中不可或缺的一部分中不可或缺的一部分。在将商品准确送达客户的过程中,在将商品准确送达客户的过程中,详细地址起了重要的作用详细地址起了重要的作用。快递员通过街道小区名称可快递员通过街道小区名称可以到达住户所在的大致位置,然后根据建筑的标号和门以到达住户所在的大致位置,然后根据建筑的标号和门牌号快速定位并将商品送达牌号快速定位并将商品送达。在字符串操作中,同样可在字符串操作中,同样可以根据地址(字符所在的索引)查找字符,同时还能查以根据地址(字符所在的索引)查找字符,同时还能查找特定字符对应的地址找特定字符对应的地址。字符串的查询操作主要有按索引位置查询和按值查字符串的查询操作主要有按索引位置查
13、询和按值查询两种,前者是通过字符的索引位置获取对应位置的值,询两种,前者是通过字符的索引位置获取对应位置的值,后者是通过值来获取其所对应的位置索引。查询的顺序后者是通过值来获取其所对应的位置索引。查询的顺序可以是从前向后,也可以是从后向前,还可以指定开始可以是从前向后,也可以是从后向前,还可以指定开始查询的索引位置。字符串查询操作如案例查询的索引位置。字符串查询操作如案例 4-4 4-4 所示。所示。运行结果如图运行结果如图 4-4 4-4 所示。所示。图图 4-4 运行结果运行结果 此案例仅仅是一些简单方法的使用,在实际应用中,多此案例仅仅是一些简单方法的使用,在实际应用中,多个方法可以嵌套
14、使用,用于达成实际的目的。例如案例个方法可以嵌套使用,用于达成实际的目的。例如案例 4-4 4-4 中,有一个从中,有一个从 12 12 位置开始查询第一个位置开始查询第一个 Java Java 所在位置的操所在位置的操作,就可以多个查询方法一起使用。作,就可以多个查询方法一起使用。首先观察字符串首先观察字符串“Hello Java,Hello Java String”“Hello Java,Hello Java String”,想要反向查询在字符串中出现的第一个想要反向查询在字符串中出现的第一个 Java Java,只要定位在最,只要定位在最后一个后一个“Hello”“Hello”之前就可以
15、。同理,因为之前就可以。同理,因为“,”也在第一个也在第一个 Java Java 之前,利用之前,利用“,”所在的位置来查询也能达到同样的目所在的位置来查询也能达到同样的目的,代码如下。的,代码如下。str.lastIndexOf(Java,str.lastIndexOf(H)str.lastIndexOf(Java,str.lastIndexOf(H)str.lastIndexOf(Java,str.indexOf(,)str.lastIndexOf(Java,str.indexOf(,)2 2字符串修改操作字符串修改操作 字符串的修改操作在字符串的修改操作在 String String 类
16、中只有一些简单的截取、类中只有一些简单的截取、分割和连接,较为复杂的字符串操作方法在分割和连接,较为复杂的字符串操作方法在 StringBufferStringBuffer和和 StringBuilderStringBuilder 中,一般在不需要考虑性能的情况下,中,一般在不需要考虑性能的情况下,StringString 类提供的方法已经足够,如案例类提供的方法已经足够,如案例 4-5 4-5 所示所示。运行结果如图运行结果如图 4-5 4-5 所示所示。图图 4-5 运行结果运行结果 字符串的替换操作有字符串的替换操作有 replace replace、replaceAll replace
17、All 和和repalceFirstrepalceFirst。replace replace 类似类似 repalceAll repalceAll,唯一的区,唯一的区别是别是 replaceAll replaceAll支持正则表达式的替换方式,但是支持正则表达式的替换方式,但是 repalce repalce 只支持字符或者字符串替换,这两个方法都是只支持字符或者字符串替换,这两个方法都是全局替换的。如果只想替换其中一个,全局替换的。如果只想替换其中一个,repalceFirst repalceFirst 是个不错的选择,在实际开发过程中,结合其他几种字是个不错的选择,在实际开发过程中,结合其
18、他几种字符串操作方法可以达到复杂的处理逻辑。符串操作方法可以达到复杂的处理逻辑。在字符串中,两个字符串相加,例如:在字符串中,两个字符串相加,例如:String str=Hello;String str=Hello;System.out.println(str+David!);System.out.println(str+David!);System.out.println(str.concat(David!);System.out.println(str.concat(David!);运行结果如图运行结果如图 4-6 4-6 所示。所示。图图 4-6 运行结果运行结果 从运行结果可以看出,从
19、运行结果可以看出,“+”“+”可以实现与可以实现与 concat concat 相同的功能,这是字符相同的功能,这是字符“+”“+”重载的原因,可便于简单重载的原因,可便于简单的字符串的拼接操作。如果只是少量使用的简单字符串的字符串的拼接操作。如果只是少量使用的简单字符串拼接操作,直接使用拼接操作,直接使用“+”“+”来实现更易于阅读与维护。来实现更易于阅读与维护。3 3字符串分割操作字符串分割操作 之前提到,字符串其实就是一组字符的集合,那么,之前提到,字符串其实就是一组字符的集合,那么,字符串理应可以分割成一个个字符序列或是一组组字符字符串理应可以分割成一个个字符序列或是一组组字符序列序列
20、。事实也正是如此,字符串操作类事实也正是如此,字符串操作类 String String 提供了提供了这些功能,如案例这些功能,如案例 4-6 4-6 所示所示。运行结果如图运行结果如图 4-7 4-7 所示所示。图图 4-7 运行结果运行结果 此案例中结合了查询操作与修改操作,将获取的子串中此案例中结合了查询操作与修改操作,将获取的子串中的所有的所有 e e 替换成了下划线,在子串替换时直接调用了替换成了下划线,在子串替换时直接调用了replace()replace()方法,这是因为这些方法在调用后返回的也是一方法,这是因为这些方法在调用后返回的也是一个字符串对象,因此这个对象仍可以继续调用字
21、符串的操作个字符串对象,因此这个对象仍可以继续调用字符串的操作方法。方法。在获取子串时,在获取子串时,e e 后面是一个空格,结合其父字符串,后面是一个空格,结合其父字符串,可以发现字符串的截取是含头不含尾的截取方式,例如:可以发现字符串的截取是含头不含尾的截取方式,例如:String str=Hello;String str=Hello;str.substring(0,1);/str.substring(0,1);/返回返回H H,不返回,不返回HeHe 这是字符串比较特殊的一点,在截取字符串的时候用这是字符串比较特殊的一点,在截取字符串的时候用 indexOf indexOf 需要格外小心
22、,这个索引位置在开始截取位置和结需要格外小心,这个索引位置在开始截取位置和结束截取位置时需要区别对待。束截取位置时需要区别对待。4 4字符串比较操作字符串比较操作 字符串的比较是字符串中最常见的操作,例如之前字符串的比较是字符串中最常见的操作,例如之前网络上很火的网络上很火的“4396”“4396”在某些公司的一些应用中被限制在某些公司的一些应用中被限制使用了,这就涉及字符串的比较和替换操作。使用了,这就涉及字符串的比较和替换操作。运行结果如图运行结果如图 4-8 4-8 所示所示。图图 4-8 运行结果运行结果 比较字符串的值使用比较字符串的值使用 equals equals,是否含有该字符
23、串,是否含有该字符串的比较使用的比较使用 contains contains。值得一提的是,。值得一提的是,compareTo compareTo 方方法在比较长度相同的字符串的时候,会返回第一个不相法在比较长度相同的字符串的时候,会返回第一个不相同的字符的字典值的差值,该差值可能为正也可能为负;同的字符的字典值的差值,该差值可能为正也可能为负;如果两个字符串的长度不相同,那么该方法会返回两个如果两个字符串的长度不相同,那么该方法会返回两个字符串的长度差。另外,字符串的长度差。另外,equals equals 和和 compareTo compareTo 都包都包含不区分大小写的比较方法,含不
24、区分大小写的比较方法,equalsIgnoreCase equalsIgnoreCase 和和 compareToIgnoreCase compareToIgnoreCase 也是需要注意的。也是需要注意的。在在 Java Java 中字符是严格区分大小写的,我们从中字符是严格区分大小写的,我们从“字字符串符串 SUN SUN 和字符串和字符串 sun sun 是否相等:是否相等:false”false”和和“字符字符串串 SUN SUN 和字符串和字符串 sun sun 是否忽略大小写相等:是否忽略大小写相等:true”true”的的输出中就能得出这个结论。所以在实际开发中,如果不输出中就能
25、得出这个结论。所以在实际开发中,如果不需要考虑大小写的情况,可以使用需要考虑大小写的情况,可以使用 IgnoreCase IgnoreCase 结尾的结尾的方法,或者全部转换成大写或小写之后再进行比较。方法,或者全部转换成大写或小写之后再进行比较。4.1.3 4.1.3 拓展:不变的字符串拓展:不变的字符串 String String 是是 Java Java 中最常用的类之一,同时中最常用的类之一,同时 String String 类也是类也是 final final 关键字限定的类关键字限定的类。在。在 Java Java 中,字符使用中,字符使用 unicodeunicode 编码,每个
26、字符占两位,汉字也只占用两位,但编码,每个字符占两位,汉字也只占用两位,但是属于一个字符是属于一个字符。1 1关键字:关键字:final final final final 在在 Java Java 中是一个保留的关键字,可以声明中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量成员变量、方法、类以及本地变量。一旦你将引用声明作一旦你将引用声明作 finalfinal,你将不能改变这个引用了,编译器会检查代码,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误如果你试图将变量再次初始化的话,编译器会报编译错误。(1 1)限定变量:凡是对成员变
27、量或者本地变量(在方法)限定变量:凡是对成员变量或者本地变量(在方法中的或者代码块中的变量称为本地变量)声明为中的或者代码块中的变量称为本地变量)声明为 final final的都叫作的都叫作 final final 变量。变量。final final 变量经常和变量经常和 static static 关关键字一起使用,作为常量,例如:键字一起使用,作为常量,例如:public static final String ZERO=“0”;public static final String ZERO=“0”;(2 2)限定方法:)限定方法:final final 也可以声明方法。方法前面加上也可
28、以声明方法。方法前面加上 final final 关键字,代表这个方法不可以被子类的方法重写。关键字,代表这个方法不可以被子类的方法重写。如果你认为一个方法的功能已经足够完整了,子类中不需如果你认为一个方法的功能已经足够完整了,子类中不需要改变的话,你可以声明此方法为要改变的话,你可以声明此方法为 final final。final final 方法比方法比非非final final 方法要快,因为在编译的时候已经静态绑定了,方法要快,因为在编译的时候已经静态绑定了,不需要在运行时再动态绑定,例如:不需要在运行时再动态绑定,例如:public final String getName()pub
29、lic final String getName()return“Name”return“Name”;(3 3)限定类:使用)限定类:使用 final final 来修饰的类叫作来修饰的类叫作 final final 类。类。final final 类的功能通常是完整的,它们不能被继承。类的功能通常是完整的,它们不能被继承。Java Java 中有许多类是中有许多类是 final final 的,譬如的,譬如 String String、Interger Interger 以以及其他包装类。例如:及其他包装类。例如:public final class GlassCup public fina
30、l class GlassCup /此处省略此处省略 final final 类型的优点如下。类型的优点如下。l 提高性能,提高性能,JVM JVM 和和 JAVA JAVA 应用均会缓存应用均会缓存 final final 限定限定的变量。的变量。l final final 变量在多线程环境下无须额外开销即可共享。变量在多线程环境下无须额外开销即可共享。l 会对会对 final final 类型的变量、方法和类进行优化。类型的变量、方法和类进行优化。2 2字符串不可变性字符串不可变性 String String strstr=“Hello”;=“Hello”;System.out.print
31、lnSystem.out.println(str.substringstr.substring(0,1);(0,1);System.out.printlnSystem.out.println(strstr););以上的代码会输出什么呢以上的代码会输出什么呢?str.replacestr.replace(“H”,“h”);(“H”,“h”);System.out.printlnSystem.out.println(strstr););这次输出是什么呢这次输出是什么呢?输出结果如图输出结果如图 4-9 4-9 所示所示。图图 4-9 运行结果运行结果 控制台仍然输出控制台仍然输出“Hello”“H
32、ello”是什么原因呢?原来,是什么原因呢?原来,字符串的方法在返回时返回的是另外一个字符串,而其字符串的方法在返回时返回的是另外一个字符串,而其本身并没有改变,所以无论如何修改,只要不对对象重本身并没有改变,所以无论如何修改,只要不对对象重新赋值,那么该对象就不会改变。也正是这一点,使得新赋值,那么该对象就不会改变。也正是这一点,使得字符串在使用的时候无须额外的开销就能实现共享。字符串在使用的时候无须额外的开销就能实现共享。4.2 StringBuffer 4.2 StringBuffer 类类 字符串类字符串类 String String 是是 final final 限定的类型,在多线程
33、编限定的类型,在多线程编程的时候因为其不变性的特点,使得其在多线程中共享时不程的时候因为其不变性的特点,使得其在多线程中共享时不会有额外的开销,这极大地提升了性能,同时也带来了问题会有额外的开销,这极大地提升了性能,同时也带来了问题。不变的对象有时候会极大地提升程序的性能,但也可能会耗不变的对象有时候会极大地提升程序的性能,但也可能会耗尽系统资源尽系统资源。如下面的代码如下面的代码:String String strstr=abcabc+bcsbcs;这段代码看似简单,但实际上程序创建了这段代码看似简单,但实际上程序创建了 3 3 个字符串个字符串对象,分别是对象,分别是“abc”“bcs”“
34、abc”“bcs”和和“abcbcs“abcbcs”。如果这样的如果这样的拼接数量不断增加,会使程序系统产生极大的性能消耗,这拼接数量不断增加,会使程序系统产生极大的性能消耗,这是需要极力避免的情况是需要极力避免的情况。Java Java 使用了使用了 StringBufferStringBuffer 和和StringBuiderStringBuider 两个类来处理这个问题两个类来处理这个问题。4.2.1 StringBuffer 4.2.1 StringBuffer 的应用的应用 StringBufferStringBuffer 在字符串的操作上克服了在字符串的操作上克服了 String
35、String 拼接会产生多个对象的问题拼接会产生多个对象的问题。它可以以一它可以以一个字符串作为参数进行初始化个字符串作为参数进行初始化。其常用初始化方式其常用初始化方式有以下有以下 3 3 种。种。StringBufferStringBuffer strBufferstrBuffer=new =new StringBufferStringBuffer();/();/无参无参构造函数初始化构造函数初始化 StringBufferStringBuffer stringBufferstringBuffer=new =new StringBufferStringBuffer(123);(123);/
36、使用字符串对象初始化使用字符串对象初始化 StringBufferStringBuffer stBufferstBuffer=new =new StringBufferStringBuffer(strBufferstrBuffer););/使用另一个使用另一个StringBufferStringBuffer对象初始化对象初始化1 1字符串拼接插入字符串拼接插入 StringBufferStringBuffer 主要使用主要使用 append()append()方法进行字符串方法进行字符串的拼接操作,同时,也可以使用的拼接操作,同时,也可以使用 insert()insert()方法有针对性方法有
37、针对性地进行插入地进行插入。在操作完成之后,可以使用在操作完成之后,可以使用 toStringtoString()()方方法返回字符串对象法返回字符串对象。运行结果如图运行结果如图 4-11 4-11 所示所示。图图 4-11 运行结果运行结果 从运行结果可知,从运行结果可知,StringBuffer StringBuffer 的的append()append()方法可以方法可以追加任何类型的值,并将之转换成字符串添加到追加任何类型的值,并将之转换成字符串添加到StringBufferStringBuffer对象的末尾。对象的末尾。StringBuffer StringBuffer 将将 bo
38、olean boolean 类型类型的变量的值当成是字面量追加到末尾,而其他类型则直接当成的变量的值当成是字面量追加到末尾,而其他类型则直接当成一个字符进行追加。一个字符进行追加。StringBuffer StringBuffer 还有还有 insert insert 方法可以在指定位置插入方法可以在指定位置插入传入的值,传入的值,insert insert 也会将也会将 boolean boolean 类型的变量以字面量值类型的变量以字面量值插入到指定的索引位置,该索引位置的值依次向后移动。插入到指定的索引位置,该索引位置的值依次向后移动。Insert Insert 还可以接受一个字符序列作
39、为参数,从指定的字符序还可以接受一个字符序列作为参数,从指定的字符序列索引位置取出指定长度的字符序列,插入到列索引位置取出指定长度的字符序列,插入到 StringBuffer StringBuffer 对象的指定索引位置,该索引位置及之后的字符依次向后移动。对象的指定索引位置,该索引位置及之后的字符依次向后移动。在案例中,打印在案例中,打印 StringBuffer StringBuffer 对象的时候并没有对象的时候并没有使用使用 toString()toString()方法,这是因为系统的输入输出方法方法,这是因为系统的输入输出方法会把传入的参数转换成字符串后输出,这相当于对所有会把传入的
40、参数转换成字符串后输出,这相当于对所有的打印目标都添加了一个的打印目标都添加了一个toString()toString()方法,因此,在此方法,因此,在此处可以省去处可以省去toString()toString()方法。方法。2 2字符串修改字符串修改 相较于字符串类,相较于字符串类,StringBufferStringBuffer 添加了一些新的添加了一些新的功能,它不仅可以拼接字符串或者在特定的位置插入字功能,它不仅可以拼接字符串或者在特定的位置插入字符串,还可以删除指定索引上的字符,使用起来相当方符串,还可以删除指定索引上的字符,使用起来相当方便便。运行结果如图运行结果如图 4-12 4
41、-12 所示所示。图图 4-12 运行结果运行结果 从案例从案例 4-9 4-9 可知,可知,StringBuffer StringBuffer 中的中的 delete delete 方法能够很灵活地删除字符串中的数据,配合方法能够很灵活地删除字符串中的数据,配合 insert()insert()方法可以快速实现字符串的修改操作。从输出结果可以方法可以快速实现字符串的修改操作。从输出结果可以看出,看出,StringBuffer StringBuffer 对象的修改是持久的。对象的修改是持久的。很有意思的是,其很有意思的是,其 replace replace 方法与方法与 String Stri
42、ng 的的replace replace 方法有所不同。在方法有所不同。在 String String 中,中,replace()replace()方方法会替换符合条件的所有字符,其参数是两个字符串:法会替换符合条件的所有字符,其参数是两个字符串:一个匹配项和一个匹配后需要将其匹配项替换的字符串。一个匹配项和一个匹配后需要将其匹配项替换的字符串。在在 StringBuffer StringBuffer 中,中,replace()replace()则是三个参数,分别则是三个参数,分别是起始索引位置、结束索引位置和需要将此索引区间替换成是起始索引位置、结束索引位置和需要将此索引区间替换成的字符串项
43、。在需要替换预定格式的字符串的固定位置序列的字符串项。在需要替换预定格式的字符串的固定位置序列时,该方法非常方便。时,该方法非常方便。在在StringBuferStringBufer的这些输出中不难看出,的这些输出中不难看出,StringBuffer StringBuffer 对于字符串的操作也是对于字符串的操作也是“含头不含尾含头不含尾”的处理方式。在替换的处理方式。在替换索引位置索引位置 0 0 至索引位置至索引位置 2 2 的操作里,替换操作只替换了索的操作里,替换操作只替换了索引位置引位置 0 0 和索引位置和索引位置 1 1。这种处理方式一定要牢记。这种处理方式一定要牢记。4.2.2
44、 StringBuilder 4.2.2 StringBuilder 与与 StringBuffer StringBuffer 的比较的比较 StringBuilderStringBuilder 也是官方也是官方 API API 中设计的用来操作中设计的用来操作字符串的方法类,字符串的方法类,StringBuilderStringBuilder 到底有哪些方法呢到底有哪些方法呢?下面我们通过一个案例来学习这个类下面我们通过一个案例来学习这个类。运行结果如图运行结果如图 4-13 4-13 所示所示。图图 4-13 运行结果运行结果 StringBuffer StringBuffer 和和 St
45、ringBuilder StringBuilder 的直接父类都的直接父类都是是 AbstractStringBuilder AbstractStringBuilder。它们唯一的区别就是,。它们唯一的区别就是,StringBuffer StringBuffer 的每个方法上都多了一个的每个方法上都多了一个synchronized synchronized 关键字。关键字。synchronized synchronized 关键字相当于给跑道设置了边关键字相当于给跑道设置了边界,选手不会出现因为不小心跑到其他选手的跑道而导界,选手不会出现因为不小心跑到其他选手的跑道而导致比赛混乱的情况。致比赛
46、混乱的情况。StringBuffer StringBuffer 是线程安全的,而是线程安全的,而 StringBuilder StringBuilder 则不是。在编写程序的时候如果判定不需要考虑多线程则不是。在编写程序的时候如果判定不需要考虑多线程环境,那么首选环境,那么首选StringBuilderStringBuilder,因为无须考虑多线程,因为无须考虑多线程,也就如同避免了选手会跑错跑道而需要设置的栅栏,那也就如同避免了选手会跑错跑道而需要设置的栅栏,那么速度自然会更快一些。么速度自然会更快一些。4.3 4.3 常用的常用的 JavaAPI JavaAPI Java Java 为了方
47、便编程人员的快速开发,提供了大量的为了方便编程人员的快速开发,提供了大量的通用通用 APIAPI,其中最常用到的就是,其中最常用到的就是System.out.printlnSystem.out.println()(),这个方法是这个方法是 System System 类下的一个方法类下的一个方法。除了除了 System System 类类以外,还有诸如数学计算方面的以外,还有诸如数学计算方面的 Random Random 类、类、MathMath 类等类等。4.3.1 System 4.3.1 System 类类 System System 字面意思是系统,顾名思义,这个类是和字面意思是系统,
48、顾名思义,这个类是和系统属性相关的,可以用来改变当前的系统环境变量来系统属性相关的,可以用来改变当前的系统环境变量来实现某些功能实现某些功能。因为这些都是静态的方法,所以它们可因为这些都是静态的方法,所以它们可以直接使用类名调用,省去了初始化该类的步骤以直接使用类名调用,省去了初始化该类的步骤。1 1系统属性系统属性 在第在第 1 1 章中配置系统环境变量的步骤就是在配置章中配置系统环境变量的步骤就是在配置 Java Java 的编译和运行环境,当时配置的是的编译和运行环境,当时配置的是 JAVA_HOME JAVA_HOME 这个系统变量这个系统变量。如果想手动修改,除了可以在系统内通如果想
49、手动修改,除了可以在系统内通过高级系统设置选项卡去配置,还可以使用过高级系统设置选项卡去配置,还可以使用 System System 类类对这些环境变量进行修改,当然前提是你知道这些环境对这些环境变量进行修改,当然前提是你知道这些环境变量的变量的 KEY KEY 值,值,JAVA_HOME JAVA_HOME 就是一个就是一个 KEY KEY 值。值。运行结果如图运行结果如图 4-14 4-14 所示。所示。图图 4-14 运行结果运行结果 此处因内容较多,仅截取了部分内容。具体的输出此处因内容较多,仅截取了部分内容。具体的输出会因为运行的系统不同而有所差别,有兴趣的读者可以会因为运行的系统不
50、同而有所差别,有兴趣的读者可以自己运行后查看。自己运行后查看。Java Java可以通过可以通过SystemSystem类来获取当前系统的环境变量,类来获取当前系统的环境变量,如案例如案例4-114-11中的中的System.getProperties()System.getProperties()方法。同时方法。同时SystemSystem类还可以根据环境变量的名称来获取该值。在需类还可以根据环境变量的名称来获取该值。在需要的时候,也可以通过要的时候,也可以通过 System System 来修改甚至添加系统环来修改甚至添加系统环境变量的值,同时也能将其删除。如案例境变量的值,同时也能将其删
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。