Java09-字符串

1.String类

1.1String类概述

String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例。也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象。String 类在 java.lang 包下,所以使用的时候不需要导包!

1.2String类的特点

  • 字符串不可变,它们的值在创建后不能被更改
  • 虽然 String 的值是不可变的,但是它们可以被共享
  • 字符串效果上相当于字符数组( char[] ),但是底层原理是字节数组( byte[] )

1.3String类的构造方法

  • 常用的构造方法

    方法名 说明
    public String() 创建一个空白字符串对象,不含有任何内容
    public String(char[] chs) 根据字符数组的内容,来创建字符串对象
    public String(byte[] bys) 根据字节数组的内容,来创建字符串对象
    String s = “abc”; 直接赋值的方式创建字符串对象,内容就是abc

1.4创建字符串对象两种方式的区别

  • 通过构造方法创建
    通过 new 创建的字符串对象,每一次 new 都会申请一个内存空间,虽然内容相同,但是地址值不同

  • 直接赋值方式创建
    当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在。 不存在:创建新的 存在:复用

String是个引用类型,有它的属性和方法,继承obj,只不过重写了返回的对象是他自己,也就是字符组。

赋值:在串池里面,new出来的:在堆里面
串池也是堆内存中开辟的一个空间

1.5字符串的比较

1.5.1 == 号的作用

  • 比较基本数据类型:比较的是具体的值
  • 比较引用数据类型:比较的是对象地址值

1.5.2equals方法的作用

  • 方法介绍
1
2
boolean result = s1.equals(s2)     比较两个字符串内容是否完全相同、区分大小写
equalsIgnoreCase 忽略大小写
  • 示例代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    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 == s2);
    System.out.println(s1 == s3);
    System.out.println(s3 == s4);
    System.out.println("--------");

    //比较字符串内容是否相同
    System.out.println(s1.equals(s2));
    System.out.println(s1.equals(s3));
    System.out.println(s3.equals(s4));
    }
    }

1.6遍历字符串案例

. charAt(索引)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 字符串直接遍历
public class Test2 {
public static void main(String[] args) {
//两个方法:
//charAt():会根据索引获取对应的字符
//length(): 会返回字符串的长度
//遍历
String str = "123456";
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
System.out.println(c);
}
}
}

1.7统计字符次数案例

1.7.1案例需求

键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数(不考虑其他字符)

1.7.2代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 统计个数
public class Test4 {
public static void main(String[] args) {
//键盘录入一个字符串,统计大写,小写,数字出现的次数


//1.键盘录入一个字符串
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String str = sc.next();


//2.统计 --- 计数器count
//此时我要统计的有3样东西,所以要定义3个计数器分别进行统计
int bigCount = 0;
int smallCount = 0;
int numberCount = 0;
//得到这个字符串里面每一个字符
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
//对c进行判断
if (c >= 'a' && c <= 'z') {
smallCount++;
}else if(c >= 'A' && c <= 'Z'){
bigCount++;
}else if(c >= '0' && c <= '9'){
numberCount++;
}
}

//3.当循环结束之后,三个变量记录的就是对应的个数
System.out.println("大写字符有:" + bigCount + "个");
System.out.println("小写字符有:" + smallCount + "个");
System.out.println("数字字符有:" + numberCount + "个");
}
}

1.8 金额转换

1.8.1 案例需求

把2135变成:零佰零拾零万贰仟壹佰叁拾伍元 

把789变成:零佰零拾零万零仟柒佰捌拾玖元

1.8.2 代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import java.util.Scanner;

public class StringDemo {
public static void main(String[] args) {
//1.键盘录入一个金额
Scanner sc = new Scanner(System.in);
int money;
while (true) {
System.out.println("请录入一个金额");
money = sc.nextInt();
if (money >= 0 && money <= 9999999) {
break;
} else {
System.out.println("金额无效");
}
}

//定义一个变量用来表示钱的大写
String moneyStr = "";

//2.得到money里面的每一位数字,再转成中文
while (true) {//2135
//从右往左获取数据,因为右侧是数据的个位
int ge = money % 10;
String capitalNumber = getCapitalNumber(ge);
//把转换之后的大写拼接到moneyStr当中
moneyStr = capitalNumber + moneyStr;
//第一次循环 : "伍" + "" = "伍"
//第二次循环 : "叁" + "伍" = "叁伍"
//去掉刚刚获取的数据
money = money / 10;

//如果数字上的每一位全部获取到了,那么money记录的就是0,此时循环结束
if (money == 0) {
break;
}
}

//3.在前面补0,补齐7位
int count = 7 - moneyStr.length();
for (int i = 0; i < count; i++) {
moneyStr = "零" + moneyStr;
}
System.out.println(moneyStr);//零零零贰壹叁伍

//4.插入单位
//定义一个数组表示单位
String[] arr = {"佰","拾","万","仟","佰","拾","元"};
// 零 零 零 贰 壹 叁 伍

//遍历moneyStr,依次得到 零 零 零 贰 壹 叁 伍
//然后把arr的单位插入进去

String result = "";
for (int i = 0; i < moneyStr.length(); i++) {
char c = moneyStr.charAt(i);
//把大写数字和单位拼接到result当中
result = result + c + arr[i];
}

//5.打印最终结果
System.out.println(result);

}


//定义一个方法把数字变成大写的中文
//1 -- 壹
public static String getCapitalNumber(int number) {
//定义数组,让数字跟大写的中文产生一个对应关系
String[] arr = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
//返回结果
return arr[number];
}

}

1.9 手机号屏蔽

需求:以字符串的形式从键盘接受一个手机号,将中间四位号码屏蔽

最终效果为:131****9468

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 手机号屏蔽
public class Test8 {
public static void main(String[] args) {
/*以字符串的形式从键盘接受一个手机号,将中间四位号码屏蔽
最终效果为:131****9468*/

//1.键盘录入一个手机号码
Scanner sc = new Scanner(System.in);
System.out.println("请输入手机号码");
String phoneNumber = sc.next();//13112349408

//2.截取手机号码中的前三位
String star = phoneNumber.substring(0, 3);

//3.截取手机号码中的最后四位
//此时我用substring方法,是用1个参数的,还是两个参数的?1个参数的会更好
//因为现在我要截取到最后,所以建议使用1个参数的。
String end = phoneNumber.substring(7);

//4.拼接
String result = star + "****" + end;

System.out.println(result);

}
}

1.10 敏感词替换

需求1:键盘录入一个 字符串,如果字符串中包含(TMD),则使用***替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 敏感词替换
public class Test9 {
public static void main(String[] args) {
//1.定义一个变量表示骂人的话
String talk = "TMD";


//2.把这句话中的敏感词进行替换
String result = talk.replace("TMD", "***");

//3.打印
System.out.println(talk);
System.out.println(result);
}
}

需求2:如果要替换的敏感词比较多怎么办?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 多个敏感词替换
public class Test10 {
public static void main(String[] args) {
//实际开发中,敏感词会有很多很多

//1.先键盘录入要说的话
Scanner sc = new Scanner(System.in);
System.out.println("请输入要说的话");
String talk = sc.next();//TMD,GDX,ctmd,ZZ

//2.定义一个数组用来存多个敏感词
String[] arr = {"TMD","GDX","ctmd","ZZ","lj","FW","nt"};

//3.把说的话中所有的敏感词都替换为***

for (int i = 0; i < arr.length; i++) {
//i 索引
//arr[i] 元素 --- 敏感词
talk = talk.replace(arr[i],"***");
}

//4.打印结果
System.out.println(talk);//***,***,***,***

}
}

1.11 身份证信息查看

身份证的每一位都是有固定的含义:
  • 1、2位:省份
  • 3、4位:城市
  • 5、6位:区县
  • 7-14位:出生年、月、日
  • 15、16位:所在地派出所
  • 17位:性别(奇数男性,偶数女性)
  • 18位:个人信息码(随机产生)

要求打印内容方式如下:

人物信息为:

出生年月日:XXXX年X月X日

性别为:男/女
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class StringDemo11 {
public static void main(String[] args) {
//1.定义一个字符串记录身份证号码
String id = "321281202001011234";

//2.获取出生年月日
String year = id.substring(6, 10);
String month = id.substring(10, 12);
String day = id.substring(12, 14);


System.out.println("人物信息为:");
System.out.println("出生年月日:" + year + "年" + month + "月" + day + "日");

//3.获取性别
char gender = id.charAt(16);//'3' ---> 3
//利用ASCII码表进行转换
//'0' ---> 48
//'1' ---> 49
//'2' ---> 50
//'3' ---> 51
//'4' ---> 52
//'5' ---> 53
//'6' ---> 54
//'7' ---> 55
//'8' ---> 56
//'9' ---> 57

int num = gender - 48;
if(num % 2 == 0){
System.out.println("性别为:女");
}else{
System.out.println("性别为:男");
}
}
}

2.StringBuilder

StringBuilder 可以看成是一个容器,创建之后里面的内容是可变的。

当我们在拼接字符串和反转字符串的时候会使用到

2.1 构造方法

方法名 说明
public StringBuilder() 创建一个空白可变字符串对象,不含有任何内容
public StringBuilder(String str) 根据字符串的内容,来创建可变字符串对象.初始化存在str

2.2 常用方法

方法名 说明
public StringBuilder append(任意类型) 添加数据,并返回对象本身
public StringBuilder reverse() 反转容器中的内容
public int length() 返回长度(字符出现的个数)
public String toString() 把StringBuilder转换为String

2.3 基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class StringBuilderDemo3 {
public static void main(String[] args) {
//0.创建对象
StringBuilder sb = new StringBuilder("abc");

//1.添加元素
/*sb.append(1);
sb.append(2.3);
sb.append(true);
System.out.println(sb);//结果 abc12.3true
*/

//2.反转
sb.reverse();
System.out.println(sb);//结果 cba
//3.获取长度
int len = sb.length();
System.out.println(len);//结果 3

//4.把StringBuilder变回String
String str = sb.toString();

//打印
//普及:
//因为StringBuilder是Java已经写好的类
//java在底层对他做了一些特殊处理。
//打印对象不是地址值而是属性值。
}
}

2.4 链式编程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

}
}

3. StringJoiner

  • StringJoiner跟StringBuilder一样,也可以看成是一个容器,创建之后里面的内容是可变的。
  • 作用:提高字符串的操作效率,而且代码编写特别简洁,但是目前市场上很少有人用。
  • JDK8出现的
方法名 说明
public StringJoiner(间隔符号) 指定拼接的间隔符号
public StringJoiner(间隔符号,开始符号,结束符号) 指定拼接的间隔符号,开始符号,结束符号
方法名 说明
public StringJoiner add(任意类型) 添加数据,并返回对象本身
public int length() 返回长度(字符出现的个数)
public String toString() 把StringBuilder转换为String

基本使用:

1
2
3
4
5
6
//1.创建一个对象,并指定中间的间隔符号
StringJoiner sj = new StringJoiner("---");
//2.添加元素
sj.add("aaa").add("bbb").add("ccc");
//3.打印结果
System.out.println(sj);//aaa---bbb---ccc
1
2
3
4
5
6
7
8
9
10
//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]

关于字符串的底层原理:

  1. 字符串存储的内存原理

    String s = “abc”;直接赋值

    特点:

    此时字符串abc是存在字符串常量池中的。
     
    先检查字符串常量池中有没有字符串abc,如果有,不会创建新的,而是直接复用。如果没有abc,才会创建一个新的。
    

    所以,直接赋值的方式,代码简单,而且节约内存。

  2. new出来的字符串

    看到new关键字,一定是在堆里面开辟了一个小空间。

    String s1 = new String(“abc”);

    String s2 = “abc”;

    s1记录的是new出来的,在堆里面的地址值。

    s2是直接赋值的,所以记录的是字符串常量池中的地址值。

  3. ==号比较的到底是什么?

    如果比较的是基本数据类型:比的是具体的数值是否相等。

    如果比较的是引用数据类型:比的是地址值是否相等。

    结论:==只能用于比较基本数据类型。不能比较引用数据类型。


Java09-字符串
https://blog.966677.xyz/2023/06/29/Java09-字符串/
作者
Zhou1317fe5
发布于
2023年6月29日
许可协议