Java String和StringBuilder
它作为Java
语言的内置类,String
类也为我们预先定义了很多好用的方法
前言
- Let·s get it
- 8/24,继续编程
- 不要停止向前,奥里给!!!
- 马上开学了,开学之前把Java的基础打牢了!!!
1. String 对象的创建
String对象的创建有两种方式。
第1 种方式就是我们最常见的创建字符串的方式:
String str1 = "8/24";
第 2 种方式是对象实例化的方式,使用new
关键字,并将要创建的字符串作为构造参数:
String str2 = new String("8/25");
如果调用 String 类的无参构造方法,则会创建一个空字符串:
String str3 = new String();
这种方式很少使用。
2. 获取字符串长度
可以使用length()
方法来获取字符串的长度。例如:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "8/24"; int a = str1.length(); System.out.println(a); } }
运行结果:
4
3. 字符串查找
3.1 获取指定位置字符
可以使用char charAt(int index)
方法获取字符串指定位置的字符。它接收一个整型的index
参数,指的是索引位置,那什么是索引位置呢?例如,有一字符串I love Java
,其每个字符的索引如下图所示:
可以从图示中看出,索引下标从0
开始。假如我们要获取字符C
,则为方法传入参数2
即可:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "ABCDEFG"; char a = str1.charAt(4); System.out.println(a); } }
运行结果:
E
3.2 查找字符串位置
这里介绍查找字符串位置的两个方法:
indexOf()
获取字符或子串在字符串中第一次出现的位置。lasIndexOf()
获取字符或子串在字符串中最后一次出现的位置。
这里的子串指的就是字符串中的连续字符组成的子序列。例如,字符串
Hello
就是字符串Hello Java
的子串。
indexOf()
1 获取字符在字符串中第一次出现的位置:
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "ABCDEFG"; int a = str1.indexOf('G'); System.out.println("字符A在字符串str1第一次出现的位置为:"+ a); } }
字符A在字符串str1第一次出现的位置为:6
2 获取子串在字符串中第一次出现的位置:
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "I just poor boy,I needn`t sympathy"; int a = str1.indexOf('I'); System.out.println("字串I在字符串str1第一次出现的位置为:"+ a); } }
字符I在字符串str1第一次出现的位置为:0
lastIndexOf()
1 获取字符在字符串中最后一次出现的位置:
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "I just poor boy,I needn`t sympathy"; int a = str1.lastIndexOf("I"); System.out.println("字串I在字符串str1最后一次出现的位置为:"+ a); } }
字串I在字符串str1最后一次出现的位置为:16
2 获取子串在字符串中最后一次出现的位置:
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "I love LYF and I love PYY"; int a = str1.lastIndexOf("I love"); System.out.println("子串I love在字符串str1最后一次出现的位置为:"+ a); } }
运行结果:
子串I love在字符串str1最后一次出现的位置为:15
需要特别注意的是,以上方法的参数都是区分大小写的。如果你找了个不存在的,上述方法都会返回一个整型值:-1
。我们来看以下示例:
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "I love LYF and I love PYY"; int a = str1.lastIndexOf("QQ"); System.out.println("子串QQ在字符串str1最后一次出现的位置为:"+ a); } }
子串QQ在字符串str1最后一次出现的位置为:-1
可以看到结果是-1
4. 字符串截取
字符串的截取也称为获取子串
可以使用substring()
方法来获取子串
String类中有两个重载的实例方法:
String substring(int beginIndex)
获取从beginIndex
位置开始到结束的子串。String substring(int beginIndex, int endIndex)
获取从beginIndex
位置开始到endIndex
位置的子串(不包含endIndex
位置字符)
关于这两个方法的使用,我们来看一个实例:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "I just poor boy,I need no sympathy"; String a = str1.substring(15); String b = str1.substring(8,12); System.out.println("从15到最后的字符串"+ a); System.out.println("从8到12的字符串"+ b); } }
运行结果:
从15到最后的字符串,I need no sympathy 从8到12的字符串oor
要特别注意,方法签名上有两个参数的substring(int beginIndex, int endIndex)
方法
截取的子串不包含endIndex
位置的字符。
5. 字符串切割
5.1 切割为字串数组
String[] split(String regex)
方法可将字符串切割为子串,其参数regex
是一个正则表达式分隔符,返回字符串数组。
例如,我们使用空格作为分隔符来切割I just poor boy,I need no sympathy
字符串,结果将返回含有7个元素的字符串数组:
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "I just poor boy,I need no sympathy"; String[] a = str1.split(" "); for (String index : a) { System.out.print(index+'\t'); } } }
I just poor boy,I need no sympathy
注意,有几种特殊的分隔符:*
^
:
|
.
``,要使用转义字符转义。例如:
String[] a = str2.split("\*"); String[] b = str3.split("\\"); String[] c = str4.split("\|");
String[] split(String regex, int limit)
其第二个参数limit
用以控制正则匹配被应用的次数
5.2 切割为 byte 数组
在实际工作中,网络上的数据传输就是使用二进制字节数据。因此字符串和字节数组之间的相互转换也很常用。
我们可以使用getBytes()
方法将字符串转换为byte
数组。例如:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "ABCD"; byte[] a = str1.getBytes(); for (byte index : a) { System.out.print(index + "\t"); } } }
运行结果:
65 66 67 68
将字节数组转换为字符串的方法很简单,直接实例化一个字符串对象,将字节数组作为构造方法的参数即可:
// 此处的ascii为上面通过字符串转换的字节数组 String s = new String(ascii);
6. 字符串大小写转换
字符串的大小写转换有两个方法:
toLowerCase()
将字符串转换为小写toUpperCase()
将字符串转换为大写
我们来看一个实例:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "ABCD"; String a = str1.toLowerCase(); System.out.println("小写:"+a); String b = str1.toUpperCase(); System.out.println("大写:"+b); } }
运行结果:
小写:abcd 大写:ABCD
试想,如果想把字符串HELLO world
中的大小写字母互换,该如何实现呢?
这里可以结合字符串切割方法以及字符串连接来实现:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "AB CD"; //先切割位数组 String[] a = str1.split(" "); //通过索引,分别变为大写和小写 String result = a[0].toLowerCase() + " " + a[1].toUpperCase(); System.out.println(result); } }
运行结果:
ab CD
当然,实现方式不止一种
7. 字符串比较
String
类提供了boolean equals(Object object)
方法来比较字符串内容是否相同,返回一个布尔类型的结果。
需要特别注意的是,在比较字符串内容是否相同时,必须使用equals()
方法而不能使用==
运算符。我们来看一个示例:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { String str1 = "AB CD"; String str2 = new String("AB CD"); String str3 = "AB CD"; System.out.println(str1==str2); System.out.println(str1.equals(str2)); System.out.println(str1==str3); } }
运行结果:
false true true
代码中三个字符串str1
,str2
和str3
的内容都是AB CD
,因此使用equals()
方法对它们进行比较,其结果总是为true
。
注意观察执行结果,其中使用==
运算符比较str1
和str2
的结果为true
,但使用==
运算符比较的str1
和str3
的结果为false
。
这是因为==
运算符比较的是两个变量的地址而不是内容。
我用图来解释一下!!!
1.当执行String str1 = "AB CD;"
语句时,会在内存的栈空间中创建一个str1
,在常量池中创建一个"AB CD",并将str1
指向hello
。
当执行String str2 = "hello";
语句时,栈空间中会创建一个str2
,由于其内容与str1
相同,会指向常量池中的同一个对象。所以str1
与str2
指向的地址是相同的
这就是==
运算符比较str1
和str2
的结果为true
的原因。
2.当执行String str3 = new String("hello");
语句时,使用了new
关键字创建字符串对象,由于对象的实例化操作是在内存的堆空间进行的,此时会在栈空间创建一个str3
,在堆空间实例化一个内容为hello
的字符串对象,并将str3
地址指向堆空间中的hello
,这就是==
运算符比较str1
和str3
的结果为false
的原因。
8. 小结
我们介绍了 Java String
类的常用方法:
- 使用
length()
方法可以获取字符串长度; - 使用
charAt()
、indexOf()
以及lastIndexOf()
方法可以对字符串进行查找; substring()
方法可以对字符串的进行截取,split()
、getBytes()
方法可以将字符串切割为数组;toLowerCase()
和toUpperCase()
方法分别用于大小写转换,使用equals()
方法对字符串进行比较,这里要注意,对字符串内容进行比较时,永远都不要使用==
运算符。
这些方法大多有重载方法,实际工作中,要根据合适的场景选用对应的重载方法。!!!
奥里给就完了
1. StringBuilder 概述
1.1 什么是 StringBuilder
与 String
相似,StringBuilder
也是一个与字符串相关的类
Java 官方文档给 StringBuilder
的定义是:可变的字符序列。
1.2 为什么需要 StringBuilder
在 Java 字符串的学习中,我们知道了字符串具有不可变性,当频繁操作字符串时候,会在常量池中产生很多无用的数据
而 StringBuilder
与 String
不同,它具有可变性。相较 String
类不会产生大量无用数据,性能上会大大提高。
因此对于需要频繁操作字符串的场景,建议使用 Stringbuilder
类来代替 String
类。
2. StringBuffer 概述
2.1 定义
了解了 StringBuilder
类 ,StringBuffer
也是不得不提的一个类,Java 官方文档给出的定义是:线程安全的可变字符序列。
2.2 与前者的区别
StringBuffer
是 StringBuilder
的前身,在早期的 Java
版本中应用非常广泛,它是 StringBuilder
的线程安全版本(线程我们将在后面的小节中介绍),但实现线程安全的代价是执行效率的下降。
你可以对比 StringBuilder
和 StringBuffer
的接口文档,它们的接口基本上完全一致。为了提升我们代码的执行效率,在如今的实际开发中 StringBuffer
并不常用。
3. StringBuilder 的常用方法
3.1 构造方法
StringBuilder
类提供了如下 4 个构造方法:
StringBuilder()
构造一个空字符串生成器,初始容量为 16 个字符;StringBuilder(int catpacity)
构造一个空字符串生成器,初始容量由参数capacity
指定;StringBuilder(CharSequence seq)
构造一个字符串生成器,该生成器包含与指定的CharSequence
相同的字符。;StringBuilder(String str)
构造初始化为指定字符串内容的字符串生成器。
其中第 4 个构造方法最为常用,我们可以使用 StringBuilder
这样初始化一个内容为 hello
的字符串:
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { StringBuilder str = new StringBuilder("8/24"); } }
3.2 成员方法
StringBuilder
类下面也提供了很多与 String
类相似的成员方法,以方便我们对字符串进行操作。下面我们将举例介绍一些常用的成员方法。
3.2.1 字符串连接
可以使用 StringBuilder
的 StringBuilder append(String str)
方法来实现字符串的连接操作。
我们知道,String
的连接操作是通过 +
操作符完成连接的:
String str1 = "Hello"; String str2 = "World"; String str3 = str1 + " " + str2;
如下是通过 StringBuilder
实现的字符串连接示例:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { StringBuilder str = new StringBuilder("8/24"); str.append(" "); str.append("world"); System.out.println(str); } }
运行结果:
8/24 world
由于 append()
方法返回的是一个 StringBuilder
类型,我们可以实现链式调用。例如,上述连续两个 append()
方法的调用语句,可以简化为一行语句:
//链式调用 str.append(" ").append("world");
如果你使用 IDE
编写如上连接字符串的代码,可能会有下面这样的提示(IntelliJ idea 的代码截图):
提示内容说可以将 StringBuilder
类型可以替换为 String
类型,也就是说可以将上边地代码改为:
String str = "8/24" + " " + "world";
这样写并不会导致执行效率的下降,这是因为 Java 编译器在编译和运行期间会自动将字符串连接操作转换为 StringBuilder
操作或者数组复制,间接地优化了由于 String
的不可变性引发的性能问题。
值得注意的是,append()
的重载方法有很多,可以实现各种类型的连接操作。例如我们可以连接 char
类型以及 float
类型,实例如下:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { StringBuilder str = new StringBuilder("zs的身高是"); str.append(':').append(172.5f); System.out.println(str); } }
运行结果:
zs的身高是:172.5
上面代码里连续的两个 append()
方法分别调用的是重载方法 StringBuilder append(char c)
和 StringBuilder append(float f)
。
3.2.2 获取容量
可以使用 int capacity()
方法来获取当前容量,容量指定是可以存储的字符数(包含已写入字符),超过此数将进行自动分配。注意,容量与长度(length)不同,长度指的是已经写入字符的长度。
例如,构造方法 StringBuilder()
构造一个空字符串生成器,初始容量为 16 个字符。我们可以获取并打印它的容量,实例如下:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { // 调用StringBuilder的无参构造方法,生成一个str对象 StringBuilder stringBuilder = new StringBuilder(); System.out.println(stringBuilder.capacity()); for (int i = 0; i < 17; i++) { stringBuilder.append(i); } System.out.println(stringBuilder.capacity()); } }
运行结果:
16 34
3.2.3 字符串替换
可以使用 StringBuilder replace(int start, int end, String str)
方法,来用指定字符串替换从索引位置 start
开始到 end
索引位置结束(不包含 end
)的子串。实例如下:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { // 调用StringBuilder的无参构造方法,生成一个str对象 StringBuilder stringBuilder = new StringBuilder("Hello monkey"); // 调用字符串替换方法,将 monkey 替换为 Jack stringBuilder.replace(6,12, "Jack"); System.out.println(stringBuilder); } }
在IDEA里,是有提示的
运行结果:
Hello Jack
也可使用 StringBuilder delete(int start, int end)
方法,先来删除索引位置 start
开始到 end
索引位置(不包含 end
)的子串,再使用 StringBuilder insert(int offset, String str)
方法,将字符串插入到序列的 offset
索引位置。同样可以实现字符串的替换,例如:
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { // 调用StringBuilder的无参构造方法,生成一个str对象 StringBuilder stringBuilder = new StringBuilder("Hello monkey"); stringBuilder.delete(6,12); //从第6位开始插入,内容是Jack stringBuilder.insert(6,"Jack"); System.out.println(stringBuilder); } }
3.2.4 字符串截取
可以使用 StringBuilder substring(int start)
方法来进行字符串截取,例如,我们想截取字符串的第7到第9个字符,实例如下:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { // 调用StringBuilder的无参构造方法,生成一个str对象 StringBuilder stringBuilder = new StringBuilder("Hello monkey"); String str = stringBuilder.substring(7, 9); System.out.println(str); } }
运行结果:
on
3.2.5 字符串反转
可以使用 StringBuildr reverse()
方法,对字符串进行反转操作,例如:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { // 调用StringBuilder的无参构造方法,生成一个str对象 StringBuilder stringBuilder = new StringBuilder("Hello monkey"); System.out.println(stringBuilder.reverse()); } }
运行结果:
yeknom olleH
4. 小结
今天我们介绍了 Java 的 StringBuilder
类,它具有可变性,对于频繁操作字符串的场景,使用它来代替 String
类可以提高程序的执行效率;
也知道了 StringBuffer
是 StringBuilder
的线程安全版本
完结,撒花花~~~