深入学习Java编程中的字符串的进阶使用
作者:cdai 发布时间:2023-11-11 12:54:20
JAVA虽然是在C++基础上发展而来,但却对C++的许多缺陷有所改进,其中一个不得不提的就是字符串,我们知道,随着学习的深入,进入MFC时,当处理字符串或字符时,常会需要通过_T()宏将字符或字符串变成UNICODE型,否则,会在处理中出现BUG,而在JAVA中,字符char或存储在Character类中的字符,不是一个字节,而是2个字节,采用UNICODE,这是为了支持全世界上的所有字符。
字符的序列组成字符串,有两种类型的字符串:一种是创建以后不需要修改的,称为字符串常量,在JAVA中,用String类存储;
一种是创建以后需要对其进行修改的,称为字符串变量,在JAVA中,用StringBuffer类操作和管理。
StringBuffer类
1、创建StringBuffer类对象
StringBuffer类对象表示的是字符串变量(注意是"变量"),每一个StringBuffer类对象都是可以扩充和修改的字符串变量。以下是常用的StringBuffer类构造函数:
(1)public StringBuffer()
创建一个新的空的StringBuffer类的对象,其容量初值设置成16个字符(注意是16个字符)
(2)public StringBuffer(int length)
创建一个新的空的StringBuffer类的对象,其容量初值设置成length个字符
(3)public StringBuffer(String str)
创建一个新的StringBuffer类的对象,其内容为str的内容,容量设置成str长度再加16个字符 (注意:再加上16个字符)
2、StringBuffer类对象的常用方法
(1)StringBuffer类对象的扩充
StringBuffer类提供两组方法用来扩充StringBuffer对象所包含的字符,分别是:
1)public StringBuffer append
(Object obj)
append方法用于扩充StringBuffer对象所包含的字符,该方法将指定的参数对象转化为字符串后,将其附加在原来的StringBuffer对象之后,并返回新的StringBuffer对象。附加的的参数对象可以是各种数据类型的,如int、char、String、double等。
2)public StringBuffer insert(
int插入位置offset,参数对象类型,参数对象名)
该方法将指定的参数对象转化为字符串后,将其插入在原来的StringBuffer对象中指定的位置,并返回新的StringBuffer对象。
(2)StringBuffer类对象的长度与容量
一个StringBuffer类对象的长度指的是它包含的字符个数;容量指的是被分配的字符空间的数量。
1)public int length()
该方法返回当前StringBuffer类对象包含的字符个数。
2)public int capacity()
该方法返回当前StringBuffer类对象分配的字符空间的数量。
(3)StringBuffer类对象的修改
public void setCharAt(intindex,charch)
该方法将当前StringBuffer对象中的index位置的字符替换为指定的字符ch。
(4)字符串的赋值和加法
字符串是在程序中要经常使用的数据类型,在Java编译系统中引入了字符串的赋值和加法操作。
(5)其它方法类似String类的方法
3、利用StringTokenizer类分解字符串
StringTokenizer类位于java.util包中, 在使用该类时在程序开始加上
importjava.util.StringTokenizer或
importjava.util.*
StringTokenizer类
对于StringTokenizer类,其主要作用是将字符串按照给定的分割符进行分割,其功能和String类的split方法类似
1、StringTokenizer类的构造函数
(1)StringTokenizer(Stringstr)
为给定的字符串str创建一个StringTokenizer对象,其分隔符默认设置为“\t\n\r\f”,亦即:空格、水平制表符tab、换行、回车、表格符
(2)StringTokenizer(String str,String delim)
为给定的字符串str创建一个StringTokenizer对象,其分隔符为指定的字符串delim,默认不包含分隔符
3)StringTokenizer(String str,String delim,boolean returnDelims)
为给定的字符串str创建一个StringTokenizer对象,其分隔符为指定的字符串delim,如果returnDelims为true,则创建的StringTokenizer对象中的每个字符串包含有分隔符,否则不包含分隔符
2、StringTokenizer类的常用方法
nIntcountTokens()
返回StringTokenizer对象中被分割后子字符串的个数
nBooleanhasMoreElements()
该方法的功能和hasMoreTokens()方法的功能一样
nBooleanhasMoreTokens()
检测StringTokenizer对象中是否包含分割好的子字符串,有则返回true,否则返回false
ObjectnextElement()
该方法具有nextToken()一样的功能,主要区别是它返回的不是String对象,而是一个Object对象
StringnextToken()
返回StringTokenizer对象中下一个分割好的子字符串
StringnextToken(String delim)
返回StringTokenizer对象中下一个分割好的子字符串,但是分隔符被重新设定为delim
n其实在有些编程语言中,比如C语言,其字符串就是由字符数组构成的,每个字符串的结尾用“\0”标志,但是在Java中却不是这样的。
n在Java中,字符串通常是作为String类的对象存在着,如:Strings=“I like Java!”,其中“Ilike Java!”就是一个对象。
所以说,Java中的字符串和字符数组是完全不相同的,和C语言中的字符串也是不一样的!
n为了方便字符串和字符数组的转换,在String类中提供了许多这样的构造函数和方法
n如构造函数String(char[] value)
n方法toCharArray()
方法valueOf(char[] data)
常量池
对于源程序中出现的字符串常量,当程序运行时,会统一保存到一个常量池中进行缓存。
对引用这些缓存在常量池中的字符串的变量进行比较,用==也会得到正确的结果。
但在运行时,对字符串的各种操作如+、substring等等,都是会产生新的字符串对象的。
但是强大的编译器会对字符串常量的拼接进行优化,诸如s3 = "hell" + "o"时,s3仍然会
指向常量池中的字符串。但对于变量的运算,总不能要求虚拟机执行诸如s1 + s2时还要
判断结果是否已在常量池中了吧。因此,要用equals而非==去判断两个字符串是否相等。
public static void main(String[] args) {
// String constants are put in constant pool.
String s1 = "hello";
String s2 = "hello";
String s3 = "hell" + "o";
System.out.println(s1 == s2);
System.out.println(s1 == s3);
// Operation like +,substring on string create new one.
String s4 = "hell";
String s5 = s4 + "o";
System.out.println(s1 == s5);
System.out.println(s1.equals(s5));
// substring has special handle on substring(0)
String s6 = s1.substring(0);
System.out.println(s1 == s6);
}
测试代码s1、s2、s3的字节码:
0: ldc #16; //String hello
2: astore_1
3: ldc #16; //String hello
5: astore_2
6: ldc #16; //String hello
8: astore_3
测试代码s4、s5的字节码:
41: ldc #30; //String hell
43: astore 4
45: new #32; //class java/lang/StringBuilder
48: dup
49: aload 4
51: invokestatic #34; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
54: invokespecial #40; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
57: ldc #43; //String o
59: invokevirtual #45; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
62: invokevirtual #49; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
注意一点是substring方法,substring(0,3)是得到从字符0到2的字符串。这样设计的原因
也许是这样容易计算子串的长度,3-0=3。同时substring对于特殊参数有特别的优化处理:
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);
}
由此看出,String对象背后并没有什么神奇之处,对字节码有了些了解可以更好的理解它。
其实常量池中还保存类及其方法的很多信息,如包名、类名、方法签名等等,有兴趣可以
深入研究。
![](https://www.aspxhome.com/images/zang.png)
![](https://www.aspxhome.com/images/jiucuo.png)
猜你喜欢
- 本文实例讲述了WinForm窗体间传值的方法。分享给大家供大家参考。具体实现方法如下:窗体间传递数据,无论是父窗体操作子窗体,还是子窗体操作
- 本文实例讲述了Android编程开发之TextView单击链接弹出Activity的方法。分享给大家供大家参考,具体如下:话不多说直接上码:
- Java类加载基本过程详细介绍基本过程:根据类的全限定名称加载定义类的二进制字节流。将字节流代表的静态存储结构转化为方法区的运行时数据结构内
- 大家对于 Spring 的 scope 应该都不会默认。所谓 scope,字面理解就是“作用域”、“范围”,如果一个 bean 的 scop
- 前言文章开始把我喜欢的这句话送个大家:这个世界上还有什么比自己写的代码运行在一亿人的电脑上更酷的事情吗,如果有那就是让这个数字再扩大十倍!!
- 本文实例讲述了 Android 7.0开发获取存储设备信息的方法。分享给大家供大家参考,具体如下:Android 7.0开发相较之前有不少改
- 查询数据会比较耗时,所以我们想把查询数据放在一个异步任务中,查询结果获得Cursor,然后在onPostExecute (Cursor re
- 使用udp实现消息的接收和发送代码比较简单,但是别忘记关闭防火墙进行测试。首先便是服务端,使用Socket进行实现,参考代码如下: 
- 本文实例讲述了Android编程实现启动界面的方法。分享给大家供大家参考,具体如下:最近在弄一个程序启动界面程序,在这里贴下代码。解释一下:
- 本文实现了一个有趣的小东西:使用自定义View绘图,一边画线,画出的线条渐渐变淡,直到消失。效果如下图所示:用属性动画或者渐变填充(Shad
- 本文实例讲述了C#数据绑定(DataBinding)简单实现方法。分享给大家供大家参考。具体实现方法如下:using System;usin
- 这里介绍两种方法,一种是Spannable,一种是Html.fromHtml(通过html标签来改变),实际中看您使用哪种方便选择使用即可1
- 本文实例讲述了C#实现windows form拷贝内容到剪贴板的方法。分享给大家供大家参考。具体实现方法如下:using System;us
- 经常会遇到这样的情况,我们在响应客户端请求的数据的时候需要对数据进行处理,比如数据库中的数据是int型,它可能表示某个枚举,或者其它的逻辑意
- /** * 进行BigDecimal对象的加减乘除,四舍五入等运算的工具类 * * @author Marydon * @createTi
- 从Java 5开始 引入了 JConsole。JConsole 是一个内置 Java 性能分析器,可以从命令行或在 GUI shell 中运
- 本文实例讲述了C#实现3步手动建DataGridView的方法。分享给大家供大家参考。具体如下:DataView dvCmControlIn
- 前言之前在SpringBoot项目中简单使用定时任务,不过由于要借助cron表达式且都提前定义好放在配置文件里,不能在项目运行中动态修改任务
- java中的复杂查询sql语句实现:这样的查询栏,在页面中很常见,这就是复杂查询的条件,我们可以填写一个条件或多个条件,也可以一个都不填写,
- 起源 [1946: John von Neumann, Stan Ulam, and Nick Metropolis, all a