一、String 类的特点

  • Java 程序中所有双引号字符串,都是 String 类的对象。
  • 字符串在创建之后,其内容不可更改。
    如果想要更改,只能使用新的对象做替换。
  • 字符串虽然不可改变,但是可以被共享。
    在使用双引号创建字符串对象时,会检查字符串常量池中是否存在该对象,如果不存在则创建对象,如果存在则复用该对象。

二、String 类常见构造方法

1、public String ( ):创建一个空白字符串,里面不含任何内容

String s1 = new String();

2、public String (char[ ] chs):根据传入的字符串数组,创建字符串对象

char[] chs = {'a', 'b', 'c'};
String s1 = new String(chs); //此时对象s1为abc

3、public String (String original):根据传入的字符串,来创建字符串对象

String s1 = new String("abc"); //此时对象s1为abc

三、内存分析

实例1:

Java 字符串连续两个引号 javastring拼接双引号_字符串

1、StringTest1类的字节码文件进入方法区。
2、主方法被虚拟机调用进入栈内存,随后执行主方法中的语句。
3、声明一个字符串对象 s1,等号右边使用双引号创建字符串变量 “abc” ,在创建字符串变量的时候,检查堆内存中字符串常量池中是否存在该字符串变量,发现并不存在,所以创建该变量,随后将 “abc” 变量的地址交给字符串对象 s1。
4、继续声明一个字符串对象 s2,等号右边使用双引号创建字符串变量 “abc” ,同理,也要进入字符串常量池中检查是否存在该对象,发现已经存在,则直接复用,所以字符串对象 s2 也是记录着变量 “abc” 的地址。
5、对象 s1 和对象 s2 都记录着相同的地址,所以打印输出为 true。

实例2:

Java 字符串连续两个引号 javastring拼接双引号_Java 字符串连续两个引号_02

1、StringTest1类的字节码文件进入方法区。
2、主方法被虚拟机调用进入栈内存,随后执行主方法中的语句。
3、声明一个字符串对象 s1,等号右边使用双引号创建字符串变量 “abc” ,在创建字符串变量的时候,检查堆内存中字符串常量池中是否存在该字符串变量,发现并不存在,所以创建该变量,随后将 “abc” 变量的地址交给字符串对象 s1。
4、继续声明一个字符串对象 s2,等号右边出现了 new,注意此时应在堆内存中另外开辟一个独立空间,同时也有使用双引号创建字符串变量 “abc”,同理,也要进入字符串常量池中检查是否存在该对象,发现已经存在,则直接复用,将字符串常量池中字符串变量 “abc” 的地址拷贝一份交给 new 开辟的空间,最后将 new 开辟空间的地址交给字符串对象 s2。
5、对象 s1 和对象 s2 记录着不同的地址,所以打印输出为 false。

注意:new String(“abc”) 该语句创建了两个字符串变量,一个是 new 创建的,在堆内存中有自己独立的空间,另一个是双引号创建的,该字符串变量在字符串常量池中进行维护。

实例3:

Java 字符串连续两个引号 javastring拼接双引号_Java 字符串连续两个引号_03

1、StringTest1类的字节码文件进入方法区。
2、主方法被虚拟机调用进入栈内存,随后执行主方法中的语句。
3、声明一个字符串对象 s1,等号右边使用双引号创建字符串变量 “abc” ,在创建字符串变量的时候,检查堆内存中字符串常量池中是否存在该字符串变量,发现并不存在,所以创建该变量,随后将 “abc” 变量的地址交给字符串对象 s1。
4、继续声明一个字符串对象 s2,等号右边使用双引号创建字符串变量 “ab” ,在创建字符串变量的时候,检查堆内存中字符串常量池中是否存在该字符串变量,发现并不存在,所以创建该变量,随后将 “ab” 变量的地址交给字符串对象 s2。
5、继续声明一个字符串对象 s3,等号右边存在使用双引号创建字符串变量 “c”,同理,检查堆内存中字符串常量池中是否存在该字符串变量,发现并不存在,所以创建该变量。字符串的 + 号拼接会自动创建 StringBuilder 对象以及空间,然后调用该对象中的字符串拼接方法,将字符串变量 s2 和字符串变量 “c” 在该块空间进行字符串的拼接,拼接完以后由于类型不统一,又再调用 StringBuilder 对象里面的 toString 方法,将对象类型转换为 String 类型,最后将新生成的空间地址交给字符串对象 s3。
6、对象 s1 和对象 s2 记录着不同的地址,所以打印输出为 false。

实例4:

Java 字符串连续两个引号 javastring拼接双引号_servlet_04


根据常量优化机制,字符串对象 s2 的内容在编译时的字节码文件中已经拼接为字符串变量 “abc”,所以此时该题已经转化为实例1,所以打印输出为 true。

四、String 类常用方法

1. 字符串比较内容

String 类用于比较的方法:

  • public boolean equals(要比较的字符串)
    完全一样结果才是 true,否则为 false
  • public boolean equalsIgnoreCase(要比较的字符串)
    忽略大小写的比较

案例:用户登录
需求:已知正确的用户名和密码,请用程序实现模拟用户登录。总共3次机会,登录后给出相应提示。

import java.util.Scanner;

public class TestDemo01 {
    public static void main(String[] args) {
        //定义两个字符串类型变量,模拟已经存在的用户名和密码
        String username = "Benjieming";
        String password = "123456";

        for (int i = 1; i <= 3; i++) {
            //键盘录入用户输入的用户名,密码
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入用户名:");
            String scannerusername = sc.nextLine();
            System.out.println("请输入密码:");
            String scannerpassword = sc.nextLine();

            //比对
            if (username.equals(scannerusername) & password.equals(scannerpassword)){
                System.out.println("登陆成功!");
                break;
            }
            else {
                if (i == 3){
                    System.out.println("机会已经用完,请您明天再试!");
                }
                System.out.println("输入有误,请重新输入,您还有" + (3 - i) + "次机会");
            }
        }
    }
}

2. 字符串的遍历

  • public char[ ] toCharArray(): 将字符串转换为字符数组
public static void main(String[] args) {
        String s = "Benjieming";
        char[] chs = s.toCharArray();
        for (int i = 0; i < chs.length; i++) {
            System.out.println(chs[i]);
        }
    }
  • public char chatAt(int index):根据索引找字符
public static void main(String[] args) {
        String s = "Benjieming";
        for (int i = 0; i < s.length(); i++) {
            char a = s.charAt(i);
            System.out.println(a);
        }
    }
  • public int length():返回字符串的长度

案例:统计字符次数
需求:键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数,不考虑其他字符。

import java.util.Scanner;

public class TestDemo02 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入字符串:");
        //接收输入的字符串
        String s = sc.nextLine();
        int smallCount = 0;
        int bigCount = 0;
        int numCount = 0;
        //将接收到的字符串转换为字符数组
        char[] chars = s.toCharArray();
        
        //统计字符次数
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] >= 'a' & chars[i] <= 'z'){
                smallCount++;
            }
            else if (chars[i] >= 'A' & chars[i] <= 'Z'){
                bigCount++;
            }
            else if (chars[i] >= '0' & chars[i] <= '9'){
                numCount++;
            }
        }
        System.out.println("小写字母为:" + smallCount + "个");
        System.out.println("大写字母为:" + bigCount + "个");
        System.out.println("数字字母为:" + numCount + "个");
    }
}

运行结果为:

请输入字符串:
asc23H4cYG15Ifd
小写字母为:6个
大写字母为:4个
数字字母为:5个

3. 字符串的截取

  • public String substring(int beginIndex):根据传入的索引开始做截取,截取到字符串的末尾
public static void main(String[] args) {
        String s = "Benjieming";
        String result = s.substring(3);
        System.out.println(result); //运行结果为jieming
    }
  • public String substring(int beginIndex, int endIndex):根据传入的开始和结束索引,对字符串做截取
public static void main(String[] args) {
        String s = "Benjieming";
        String result = s.substring(3,6);
        System.out.println(result); //运行结果为jie
    }

注意:该方法对于字符串的截取位置包含头,不包含尾。

案例:手机号屏蔽
需求:以字符串的形式从键盘接收一个手机号,将中间四位号码屏蔽。
例如:137****0836

import java.util.Scanner;

public class TestDemo03 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的手机号:");
        String phoneNumber = sc.nextLine();
        //截取手机号前3位
        String s1 = phoneNumber.substring(0,3);
        //截取手机号后4位
        String s2 = phoneNumber.substring(7);
        System.out.println(s1 + "****" + s2);
    }
}

运行结果为:

请输入您的手机号:
13712345678
137****5678

4. 字符串的替换

  • public String replace(旧值, 新值):替换
public static void main(String[] args) {
        String s = "Benjieming";
        String result = s.replace("jie", "xin");
        System.out.println(result); //运行结果为Benxinming
    }

注意:返回值才是替换之后的结果。

案例:敏感词替换
需求:键盘录入一个字符串,如果字符串中包含(TMD),则使用 *** 替换。

import java.util.Scanner;

public class TestDemo04 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        String result = s.replace("TMD", "***");
        System.out.println(result);
    }
}

运行结果为:

你TMD是不是有病
你***是不是有病

5. 字符串的切割

  • public String[ ] split(String regex):
    根据传入的字符串作为规则进行切割,将切割后的内容存入字符串数组中,并将字符串数组返回
public static void main(String[] args) {
        String s = "123,45,67,8";
        String[] result = s.split(",");

        for (int i = 0; i < result.length; i++) {
            System.out.println(result[i]);
        }
    }

运行结果为:

123
45
67
8

注意:先正常指定切割规则,但如果没有得到自己想要的结果,就可以尝试在规则前面加入 \\

例如:

public static void main(String[] args) {
        String s = "123.45.67.8";
        String[] result = s.split("\\.");

        for (int i = 0; i < result.length; i++) {
            System.out.println(result[i]);
        }
    }

运行结果为:

123
45
67
8

五、StringBuilder 类

1、StringBuilder 是一种可变的字符序列。

2、StringBuilder 是字符串的缓冲区,我们可以将其理解为是一种容器,这个容器可以存储任意数据类型,但是只要进入到这个容器中,全部变为字符串。

例如:

public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        System.out.println(sb);//直接打印内容,此时容器中为空

        sb.append(10);//向容器中添加数据
        System.out.println(sb);

        sb.append(10.5);//向容器中添加数据
        System.out.println(sb);

        sb.append("一二三");//向容器中添加数据
        System.out.println(sb);
    }

运行结果为:

10
1010.5
1010.5一二三

六、StringBuilder 类的构造方法

1、public StringBuilder ( ):创建一个空的字符串缓冲区(容器)

StringBuilder sb = new StringBuilder();

2、public StringBuilder (String str):创建一个字符串缓冲区,并初始化好指定的参数内容

StringBuilder sb1 = new StringBuilder(10);
StringBuilder sb2 = new StringBuilder("吴彦祖");

七、StringBuilder 类的常用成员方法

1、public StringBuilder append (任意类型):添加数据,并返回对象自己

public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append(123).append("wuyanzu").append('a');
        System.out.println(sb);
    }//运行结果为123wuyanzua

链式编程:如果调用的方法返回的结果是对象,就可以继续向下调用方法。

2、public StringBuilder reverse ( ):将缓冲区中的内容进行反转

3、public int length ( ):返回长度

4、public String toString ( ):将缓冲区中的内容以 String 字符串类型返回
注意:该方法可运用在当数据存在于 StringBuilder 中,但是要用的方法 StringBuilder 中不存在,而 String 中存在需要的方法。

八、案例分析

1. 对称字符串的判断

需求:键盘接收一个字符串,程序判断出该字符串是否是对称字符串,并在控制台打印是或不是。
思路:对拿到的字符串进行反转,如果反转之后的字符串与反转前的字符串相同,则为对称字符串。

import java.util.Scanner;

/*
    String ---> StringBuilder:
        String s = "abc";
        StringBuilder sb = new StringBuilder(s);

    StringBuilder ---> String:
        String s = sb.toString();
 */

public class TestDemo01 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个对称字符串:");
        String s = sc.nextLine();

        //将String类型转换为StringBuilder类型,目的是为了调用StringBuilder中的反转方法
        StringBuilder sb = new StringBuilder(s);
        sb.reverse();

        //s为String类型,sb为StringBuilder类型,类型不一致,需要先转换类型
        if (s.equals(sb.toString())){
            System.out.println("是对称字符串");
        }
        else {
            System.out.println("不是对称字符串");
        }
    }
}

运行结果为:

请输入一个对称字符串:
123321
是对称字符串

2. 数组中数据转换为字符串

需求:定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回。调用该方法,并在控制台输出结果。

例如:
数组为 int[ ] arr = {1,2,3};
执行方法后的输出结果为:[1, 2, 3]

public class TestDemo02 {
    public static void main(String[] args) {
        int[] arr = {1,2,3};
        String result = arrayToString(arr);
        System.out.println(result);
    }

    public static String arrayToString(int[] arr){
        //创建StringBuilder,准备进行拼接
        StringBuilder sb = new StringBuilder("[");

        //遍历数组,获取内部元素
        for (int i = 0; i < arr.length; i++) {
            //将获取到的元素拼接到字符串缓冲区
            sb.append(arr[i]);
            if (i == arr.length - 1) {
                sb.append("]");
                break;
            }
            else {
                sb.append(", ");
            }
        }
        return sb.toString();
    }
}

运行结果为:

[1, 2, 3]