目录

7.1定义

7.2不可变字符串

7.3空串与null串

7.4码点与代码单元

7.5字符串的操作(String API)

7.6构建字符串


7.1定义

从概念上讲, Java 字符串就是 Unicode 字符序列。 例如, 串“ Java” 在计算机内存储的是 J、a、 v、a四个字符的Unicode编码 。Java 没有内置的字符串类型, 而是在标准 Java 类库中提供了 一个预定义类,很自然地叫做 String。每个用双引号括起来的字符串都是 String类的一个实 例:

String e = "";

字符串的实质是char类型数组

7.2不可变字符串

不可变字符串即字符串的不可变性

解释:Java中有一个特殊的内存——常量池,我们在程序中写下:String a = "";,计算机会在常量池中开辟空间,存储“”,并将其地址(设为5245)传给a,当我们改变a的值,如:a=“JAVA”;,计算机会在常量池中重新开辟空间,存储“JAVA”,并将新的地址(设为3245)传给a,此时,5245的空间并未被回收,而是被常量池暂时报存。当我们写到 String c = "";,时计算机不会开辟空间,而是将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 = "";

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()

返回一个与构建器或缓冲器内容相同的字符串