目录
7.1定义
从概念上讲, Java 字符串就是 Unicode 字符序列。 例如, 串“ Java” 在计算机内存储的是 J、a、 v、a四个字符的Unicode编码 。Java 没有内置的字符串类型, 而是在标准 Java 类库中提供了 一个预定义类,很自然地叫做 String。每个用双引号括起来的字符串都是 String类的一个实 例:
String e = "CSDN";
字符串的实质是char类型数组
7.2不可变字符串
不可变字符串即字符串的不可变性
解释:Java中有一个特殊的内存——常量池,我们在程序中写下:String a = "CSDN";,计算机会在常量池中开辟空间,存储“CSDN”,并将其地址(设为5245)传给a,当我们改变a的值,如:a=“JAVA”;,计算机会在常量池中重新开辟空间,存储“JAVA”,并将新的地址(设为3245)传给a,此时,5245的空间并未被回收,而是被常量池暂时报存。当我们写到 String c = "CSDN";,时计算机不会开辟空间,而是将5245的空间地址传给 c 。这便是字符串的不可变性,即指已申请的字符串在一定时间内不会被销毁,改变其值时,是申请新空间存储,而不是在原空间里面改动
7.3空串与null串
空串 String e = " "; 有内存空间,没有内容;
null串 String e =null; 没有内存空间
7.4码点与代码单元
码点:指与一个编码表中的某个字符对应的编码值
代码单元:就是存储单位,一个代码单元2个字节
7.5字符串的操作(String API)
Java中的String类包含了许多方法,下面列举一些常用的
提取字串:String .substring(int a,int b)
解析:
例如:
String a = "CSDN";
String b =a.substring(0,2) // b=CS
String 表示需要用String类型的量来接收返回值
substring 是方法名
a,b 表示提取的起始与终止位置,提取时是前闭后开的
其他方法的用法与解释类似
• char charAt (int index)
返回给定位置的代码单元。除非对底层的代码单元感兴趣, 否则不需要调用这个 方法。
• int codePointAt(int Index) 5.0
返回从给定位置开始的码点。
• int offsetByCodePoints(int startlndex, int cpCount) 5.0
返回从 startlndex 代码点开始,位移 cpCount 后的码点索引。
• int compareTo(String other)
按照字典顺序,如果字符串位于 other 之前, 返回一个负数;如果字符串位于 other 之 后,返回一个正数;如果两个字符串相等,返回 0。
• IntStream codePoints() 8
将这个字符串的码点作为一个流返回。调用 toArray 将它们放在一个数组中。
• new String(int[] codePoints, int offset, int count) 5.0
用数组中从 offset 开始的 count 个码点构造一个字符串。
• boolean equals(0bject other)
如果字符串与 other 相等, 返回 true。
•boolean equalsIgnoreCase(String other )
如果字符串与 other 相等 ( 忽略大小写,) 返回 tme。
•boolean startsWith(String prefix )
•boolean endsWith(String suffix )
如果字符串以 suffix 开头或结尾, 则返回 true。
•int indexOf(String str)
•int indexOf(String str, int fromlndex )
•int indexOf(int cp)
•int indexOf(int cp, int fromlndex )
返回与字符串 str 或代码点 cp 匹配的第一个子串的开始位置。这个位置从索引 0 或 fromlndex 开始计算。 如果在原始串中不存在 str, 返回 -1。
•int 1astIndexOf(String str)
•Int 1astIndexOf(String str, int fromlndex )
•int lastindexOf(int cp)
•int 1astindexOf(int cp, int fromlndex )
返回与字符串 str 或代码点 cp 匹配的最后一个子串的开始位置。 这个位置从原始串尾 端或 fromlndex 开始计算。
•int 1ength( ) 返回字符串的长度。
•int codePointCount(int startlndex , int endlndex ) 5.0
返回 startlndex 和 endludex-l之间的代码点数量。没有配成对的代用字符将计入代码点。 參 String replace( CharSequence oldString,CharSequence newString) 返回一个新字符串。这个字符串用 newString 代替原始字符串中所有的 oldString。可 以用 String 或 StringBuilder 对象作为 CharSequence 参数。
• String substring(int beginlndex )
參 String substring(int beginlndex, int endlndex ) 返回一个新字符串。这个字符串包含原始字符串中从 beginlndex 到串尾或 endlndex-l 的所有代码单元。
• String toLowerCase( )
參 String toUpperCase( ) 返回一个新字符串。 这个字符串将原始字符串中的大写字母改为小写,或者将原始字 符串中的所有小写字母改成了大写字母。
• String t r i m( )
返回一个新字符串。这个字符串将删除了原始字符串头部和尾部的空格。
• String join(CharSequence delimiter, CharSequence ... elements ) 8
返回一个新字符串, 用给定的定界符连接所有元素
7.6构建字符串
在解释构建字符串之前,我们先来了解一下计算机的底层原理
数据在内存中是一字节一字节存储的,cup读取也是一字节一字节读的,假设cpu读一次需要耗时20ns,现在有10000字节的数据需要被读取,共耗时 20*10000 = 200000 ns,时间太长。解决方法:内存将4KB=4096B内存划分为一页(也叫做块),每页有自己的地址,数据存放时是按页存的,现在存储10000B的数据只需3页,读取时只需要读取3次,极大的减少了时间,但硬件读取是按字节读的,将页的地址转换成硬件可识别的物理地址,这便需要由操作系统来实现
现在定义 String x = “abcde” ,它需要消耗1页4KB空间,尽管它只占 5*2=10B的空间,现在将 x += x执行90000次,则它需要占用 90000*10=900000B 的空间,由于字符串的不可变性,我们可以想象这样一个场景:开始时,每次申请1页,等1页装不下了,一次申请2页,且每次申请新的空间后,之前申请的空间不会被删除,就这样一直申请,到最后每次申请200多页(900000/4096),才能将此值计算完成,由于前面申请的空间还在,这就极度的消耗了空间,(要消耗的空间=200+199+198+……+2+1页)且造成数据的大量冗余,且每次申请都需浪费时间解决方法:利用stringbuffer
buffet的内部是靠基本类型数组实现的。它的实现原理可以这样理解:利用buffer申请一个数组,如:String [ ] arr = new String[big],假设big的值非常大,大到它可以容下上例的最终结果,即200多页的数据,系统根据big给数组arr开辟空间,即一次开辟200多页,那么上例的循环加法便可以在arr数组的内部进行,这样只需一次性开200多页的空间,极大的减小了内存的消耗并且缩短了时间。这便是buffer原理。在JDK5.0中,string buffer化身为string builder类来实现该操作。
为了避免大量字符串拼接时频繁构建新的string对象,造成耗时,浪费空间的问题,可以使用string builder类,操作如下:
首先, 构建一个空的字符串构建器:
StringBuilder builder = new StringBuilder();
当每次需要添加一部分内容时, 就调用 append 方法。
builder.append(ch); // 增加单个字符
builder.append(str); // 增加字符串
在需要构建字符串时就凋用 toString 方法, 将可以得到一个 String 对象, 其中包含了构建器中的字符序列。
String completedString = builder.toString()
下面的 API 注释包含了 StringBuilder 类中的重要方法
• StringBuilder()
构造一个空的字符串构建器。
• int length()
返回构建器或缓冲器中的代码单元数量
• Stri ngBui 1 der appencl(Stri ng str)
追加一个字符串并返回 this。
• StringBui 1 der append(char c)
追加一个代码单元并返回 this。
• StringBui 1 der appendCodePoint(int cp)
追加一个代码点,并将其转换为一个或两个代码单元并返回 this。
• void setCharAt(int i ,char c) 将第 i 个代码单元设置为 c。
• StringBui 1 der insert(int offset,String str)
在 offset 位置插入一个字符串并返回 this。
• StringBuilder insert(int offset,Char c)
在 offset 位置插入一个代码单元并返回 this。
• StringBui 1 der delete(1 nt startindex,int endlndex)
删除偏移量从 startindex 到 -endlndex-1 的代码单元并返回 this。
• String toString()
返回一个与构建器或缓冲器内容相同的字符串