字符串
API
API就是一种别人已经写好的东西,我们不需要自己会写,我们只需要知道怎么使用就行
java中的API
指的就是 JDK 中提供的各种功能的 Java类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可,我们可以通过帮助文档来学习这些API如何使用。
API 帮助文档,是帮助我们程序员查询和使用的一个参考文档
常用的 String 方法
String字符串
String类概述
String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例。也就是说,Java 程序中所有的双引号字符串,都是
String 类的对象。String 类在 java.lang 包下,所以使用的时候不需要导包!
java.lang包是java的核心包,所以我们不需要进行导包
String类的特点
这里的不能进行修改是指,即使你修改了,但是原来存放数据的那一段空间仍然是存在的,并且不能够进行修改。
- 字符串不可变,它们的值在创建后不能被更改,两个字符串进行拼接后是产生了一个新的字符串.
- 虽然 String 的值是不可变的,但是它们可以被共享
- 字符串效果上相当于字符数组( char[] ),但是底层原理是字节数组( byte[] )
Java 不会字符串, 开发就会凉一半String cp1 = "我爱你"; String cp2 = cp1; System.out.println(cp1.hashCode()); System.out.println(cp2.hashCode()); cp1 = "我喜欢你"; // 更改内容后原来的字符空间所存储的数据没有变化 System.out.println(cp1); System.out.println(cp2); System.out.println(cp1.hashCode()); System.out.println(cp2.hashCode());
25052448
25052448
我喜欢你
我爱你
769834857 其又开辟了一个新的空间,但是原有的空间位置的内容并没有删除,所以我们用字符串进行拼接大数据的时候就会造成这个内存的的严重占用
25052448
**字符串常见操作**
1. String
1. StringBuilder
1. StringJonier
1. StringBuffer
1. Pattern
1. Matcher
### 字符串的创建
第一种我们直接进行赋值创建
第二种我们通过new关键字进行创建类对象
![image.png](https://qkh-markdown-1316031240.cos.ap-nanjing.myqcloud.com/obsidian/202304051513448.png)
直接创建
```java
String s1 = "qiukehao1";
System.out.println(s1);
创建空字符串
String s2 = new String();
System.out.println("qiu" + s2 + "kehao2");
创建一个字符串在赋值给另一个字符串,脱裤子放屁 ,没啥用
String s3 = new String("qiukehao3");//IDE里提示这个可以不写
System.out.println(s3);
根据字符数组进行构建,这种适合以后如果我们想修改字符串的话我们可以通过这种方式,先修改字符数组的元素,在修改字符串的元素.
char[] ch = new char[] { 'q', 'k', 'h' };
String s4 = new String(ch);
System.out.println(s4);
根据字节数组来进行构建,这个构建的并不是99,98,.97的字符串,而是根据这个数字的大小去ASICC码中进行寻找.这个的应用场景是,我们以后在网络中进行传递的是字节信息,但是字节信息我们看不懂啊,所以我们可以通过这个字符串的转换来进行应用.
byte[] bys = { 99, 98, 97 };
String s5 = new String(bys);
System.out.println(s5);
空字符串
与其他任何对象变量一样,String 变量可以是 null,这表明该变量根本没有引用任何的对象,甚至不是空字符串
测试一个对象是是否是 null 可以使用这个==操作符
注意
- 这个 null 和空字符串不一样, 空字符串是一个长度为零的字符串, 而 null 根本不是字符串
- 在 null 上调用任何方法都会导致空指针异常,
创建方式的区别
第一种我们直接进行赋值创建
第二种我们通过new关键字进行创建类对象
new出来的对象是放在堆区里面
我们通过直接赋值产生的字符串,对于新创建的字符串,并不是直接去串池去申请空间,而是去串池里去找这个有没有相同的字符串,如果有的话,我们就将这个字符串的地址进行传递回来.
优点是:简单,节约内存,缺点是会造成复用
第二种是会浪费内存,但是不会造成复用
字符串的比较
==号比较的到底是什么
如果是基本数据类型,我们比较的是具体的数据值,
如果是引用数据类型,我们比较的是两个变量的地址值
所以你直接赋值的字符串可以进行==比较,因为相同的字符串的地址是相同地址的,但是如果是通过new出来的字符串我们可以通过这个==进行判断,虽然值是相同的,但是地址不相同,所以无法通过这个==进行判断
那么我们如何比较字符串呢
我们可以通过boolean 型函数equal进行比较,public boolean equals(String s) 比较两个字符串内容是否相同、区分大小写
public class StringDemo02 {
public static void main(String[] args) {
//构造方法的方式得到对象
char[] chs = {'a', 'b', 'c'};
String s1 = new String(chs);
String s2 = new String(chs);
//直接赋值的方式得到对象
String s3 = "abc";
String s4 = "abc";
//比较字符串内容是否相同
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
System.out.println(s3.equals(s4));
}
}
String cp3 = "world";
String cp4 = "world";
String cp6 = new String("world");
String cp5 = new String("world");
System.out.println(cp3 == cp4);
System.out.println(cp3 == cp5);
System.out.println(cp5 == cp6);
true
false
false
忽略大小写的比较
equalsIgnoreCase 是我们可以进行忽略大小写的比较,这个忽略是忽略的英文,不能忽略中文的
按顺序进行比较
我们使用到了这个 compareTo 方法
字符串一次比较一个字符,直到其中一个字符串已经全部比较完毕或者发现了不匹配的字符。例如,当比较"word"和"world"时,前三个字符匹配。因为 d 的 Unicode 值小于 1 的 Unicode 值,所以”word"排在前面 (这种情况下 compareTo 返回-8》也就是 d 和 1 的 Unicode 值之差 )。
这种比较对用户可能不直观,因为它依赖于字符的 Unicode 值。"blue/green"排在"bluegreen"前面,因为/的 Unicode 值比 g 小。
除此之外
我们可以通过这个 collator 进行闯将匿名内部类来创建比较规则
子字符串
substring 方法
substring方法是我们进行截取一个字符串所用的
s.substring(1,3)就是截取0~3的字符串,返回一个字符串
s.substring(7)就是截取7之后的字符串
spilt 方法
有时候你想将这个分割符表示会的字符串中的所有子字符串都提取出来,spilt 方法就是执行这种任务的。返回一个字符串数组
public static void main(String[] args) {
String name = "qiu,ke,hao";
String[] result = name.split(",");
System.out.println(Arrays.toString(result));
for (String result2 : result) {
System.out.println(result2);
}
}
format方法
我们可以通过这个String.format方法创建不打印输出的格式化字符串
Scanner input = new Scanner(System.in);
String name = input.nextLine();
int age = input.nextInt();
String s = String.format("hello , %s world , you are my age %d", name, age);
System.out.println(s);
input.close();
String.format()
方法和字符串拼接(使用 +
运算符)在功能上有一些区别。
- 格式化能力:
String.format()
提供了更强大的格式化能力,可以根据指定的格式对参数进行格式化,并插入到字符串中。你可以使用格式说明符来控制参数的显示方式(如十进制、浮点数、日期等),还可以设置精度、宽度等格式选项。这使得String.format()
在某些情况下更灵活且更易于阅读和维护。 - 可读性和维护性:使用
String.format()
方法可以将可变部分和固定部分的字符串逻辑分离开来,使代码更易读和维护。参数插入的位置由格式字符串中的占位符%s
、%d
等表示,而不需要在字符串中手动拼接各个参数。 - 性能:在某些情况下,使用字符串拼接可能比使用
String.format()
方法更高效。字符串拼接使用简单的连接操作,不涉及额外的格式处理和解析过程,因此在大量字符串拼接的情况下,性能可能更好。如果对性能要求非常高,可以使用StringBuilder
或StringBuffer
类来执行字符串拼接操作。
总之,String.format()
方法适用于需要动态构建格式化字符串并进行复杂格式控制的场景,而字符串拼接适用于简单的字符串连接操作。选择使用哪种方法取决于具体的需求和代码的可读性、性能要求等方面的权衡。
数字和字符串的转换
将整数转化为字符串, 可调用静态方法 Integer.toString 方法浮点数的话就是用 Double 类型的方法进行试验
常见的用法
int pa = 10;
System.out.println(Integer.toString(pa));
System.out.println(Integer.toString(pa, 2));
String str = "1010";
System.out.println(Integer.parseInt(str));
System.out.println(Integer.parseInt(str, 2));
10
1010
1010
10
Integer.parseInt(str, radix)
是一个用于将字符串转换为整数的方法。第二个参数 radix
表示进制,指定了字符串中数字的进制类型。
在这个方法中,str
是要进行转换的字符串,而 radix
则指定了字符串中数字的进制类型。常见的进制类型包括:
- 2:二进制
- 8:八进制
- 10:十进制(默认值)
- 16:十六进制
例如,如果你想将一个二进制字符串转换为对应的整数,可以使用 Integer.parseInt(str, 2)
。这将返回一个整数,其值等于二进制字符串所表示的数值。
以下是一个示例:
String binaryStr = "1010";
int number = Integer.parseInt(binaryStr, 2);
System.out.println(number); // 输出:10
在上面的示例中,我们将二进制字符串 "1010" 转换为对应的整数数值 10。通过指定进制类型为 2,parseInt()
方法将按照二进制的规则来解析字符串,并返回整数结果。
StringBuilder
StringBuilder可以看作一个容器,创建以后里面的内容是可以变化的
作用是,提高字符串的操作效率
字符串的拼接,由于字符串是不可以变化的,我们字符串的拼接本质是创建了一个新的字符串,所以当拼接特别长的时候就会产生特别多的无用字符串
StringBuilder的常见方法
打印这个StringBuilder创建的对象,我们并不是打印的地址,这个和我们之前学打的对象并不太一样,因为这个StringBuilder是java已经写好的类,java在低层对他做了一些特殊处理,打印对象,不是地址值,而是属性值
注意这个StringBuilder并不是一个字符串,而是类似于一个容器,我们利用这个容器进行处理字符串,用完之后就把他给抛弃就行了
我们一般是在字符串的拼接和反转的时候用这个StringBuilder的,其他情况下我们还是用正常的String就行
链式编程
当我们在调用一个方法的时候,不需要用变量接受他的结果,可以继续调用其他方法
比如说下面这个
public class StringBuilderDemo4 {
public static void main(String[] args) {
//1.创建对象
StringBuilder sb = new StringBuilder();
//2.添加字符串
sb.append("aaa").append("bbb").append("ccc").append("ddd");
System.out.println(sb);//aaabbbcccddd
//3.再把StringBuilder变回字符串
String str = sb.toString();
System.out.println(str);//aaabbbcccddd
}
}
判断字符串是否是对称的
package StringPratice;
import java.util.Scanner;
public class 判断字符串是否对称 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入你要判断的字符串");
String str = input.next();
StringBuilder s = new StringBuilder(str);
String str2 = s.reverse().toString();
if(str.equals(str2)){
System.out.println("是");
}else System.out.println("否");
}
}
字符串的拼接
package StringPratice;
public class 字符串的拼接 {
public static void main(String[] args) {
int[] arr = {1,2,3,34};
StringBuilder s = new StringBuilder("[");
for(int i=0;i<arr.length;i++){
if(i<arr.length-1){
s.append(arr[i]).append(",");
}else s.append(arr[i]);
}
String s1 = s.append("]").toString();
System.out.println(s1);
}
}
StringJoiner
StringJoiner跟StringBuilder一样,也可以看成是一个容器,创建之后里面的内容是可变的。
作用:提高字符串的操作效率,而且代码编写特别简洁,但是目前市场上很少有人用。
JDK8出现的
可以指定这个字符串之间的间隔元素,必须指定,StringJoinner是没有空参构造的。
//1.创建一个对象,并指定中间的间隔符号
StringJoiner sj = new StringJoiner("---");
//2.添加元素
sj.add("aaa").add("bbb").add("ccc");
//3.打印结果
System.out.println(sj);//aaa---bbb---ccc
第一个是间隔符号,第二个是开始符号,第三个是结束符号
//1.创建对象
StringJoiner sj = new StringJoiner(", ","[","]");
//2.添加元素
sj.add("aaa").add("bbb").add("ccc");
int len = sj.length();
System.out.println(len);//15
//3.打印
System.out.println(sj);//[aaa, bbb, ccc]
String str = sj.toString();
System.out.println(str);//[aaa, bbb, ccc]
关于字符串的扩展
字符串存储的内存原理
String s = “abc”;直接赋值
特点:
此时字符串abc是存在字符串常量池中的。
先检查字符串常量池中有没有字符串abc,如果有,不会创建新的,而是直接复用。如果没有abc,才会创建一个新的。
所以,直接赋值的方式,代码简单,而且节约内存
== 比较的到底是什么
如果比较的是基本数据类型:比的是具体的数值是否相等。
如果比较的是引用数据类型:比的是地址值是否相等。
结论:== 只能用于比较基本数据类型。不能比较引用数据类型。
字符串拼接的原理
拼接的底层原理
没有变量的拼接和有变量的拼接
没有变量的拼接
有变量的拼接,利用了StringBuildder容器,我们先把字符串放在这个容器里,然后在转化为这个字符串
同时这个串池里面也放的有这个要拼接的字符元素
每次申请都会申请创建一个StringBuildder容器,导致这个效率很低
JDK8以后我们做了一个优化,我们会先预估分析,比如说我们拼接了三个对象,我么会先进行预估创建一个数组,将这些字符串存到这个数组里,然后在将这个数组转化字符串
StringBuilder提高效率的原理图解
StringBuilder创建的字符串对象是new出来的,所以这个是一个独立的空间,我们不能随便的利用==比较这个引用的数据类型
如果没有变量参与,都是字符拆还能直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串
如果有变量参与,每一行拼接的代码,都会在内存中创建新的字符串,浪费内存
所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存
只要有变量我们就是用new出来的
如果不是变量的拼接