day10——字符串类

此资料是根据黑马程序员Java零基础视频教程提供的笔记进行修改而成,仅用于个人学习。

学习视频:https://www.bilibili.com/video/BV17F411T7Ao/?p=96&vd_source=a0fb36c5a191d7be68335738a8b342a2


1. API

1.1 API概述

  • 什么是API

    ​ API (Application Programming Interface) :应用程序编程接口

  • java中的API

  指的就是 JDK 中提供的各种功能的 Java类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可,我们可以通过帮助文档来学习这些API如何使用。


1.2 如何使用API帮助文档

  • 打开帮助文档

在这里插入图片描述

  • 找到索引选项卡中的输入框

在这里插入图片描述

  • 在输入框中输入Random

在这里插入图片描述

  • 看类在哪个包下

在这里插入图片描述

  • 看类的描述

在这里插入图片描述

  • 看构造方法

在这里插入图片描述

  • 看成员方法

在这里插入图片描述


2. String类

2.1 String类概述

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


2.2 String类的特点

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

2.2.1 不变性

在这里插入图片描述


2.3 String类的构造方法

  • 常用的构造方法

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

    public class StringDemo01 {
          
          
        public static void main(String[] args) {
          
          
           //1.使用直接赋值的方式获取一个字符串对象
            String s1 = "abc";
            System.out.println(s1);    //abc
    
    
            //2.使用new的方式来获取一个字符串对象
            //空参构造:可以获取一个空白的字符串对象
            String s2 = new String();  //s2相当于""
            System.out.println("@" + s2 + "!");   //@!
    
            //传递一个字符串,根据传递的字符串内容再创建一个新的字符串对象,脱裤子放屁,多此一举!!!
            String s3 = new String("abc");
            System.out.println(s3);  //abc
    
            //传递一个字符数组,根据字符数组的内容再创建一个新的字符串对象
            //需求:我要修改字符串的内容。  abc  Qbc
            //abc -->  {'a','b','c'}  -->  {'Q','b','c'} --> "Qbc"
            char[] chs = {
          
          'a', 'b', 'c', 'd'};
            String s4 = new String(chs);
            System.out.println(s4); //abcd
    
            //传递一个字节数组,根据字节数组的内容再创建一个新的字符串对象
            //应用场景:以后在网络当中传输的数据其实都是字节信息
            //我们一般要把字节信息进行转换,转成字符串,此时就要用到这个构造了。
            byte[] bytes = {
          
          97, 98, 99, 100};
            String s5 = new String(bytes); //通过ASCII码将byte类型数字转化成字符,最终转换成字符串!
            System.out.println(s5); //abcd
            
            //public String():创建一个空白字符串对象,不含有任何内容
            String s6 = new String();
            System.out.println("s6:" + s6);  //s6:
        }
    }
    

2.4 new、双引号创建字符串对象的区别

  • 通过构造方法创建

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


  • 直接赋值方式创建

    ​ 以双引号“”方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM 都只会建立一个 String 对象,并在字符串池中维护


  • 字符串存储的内存原理

    String s = “abc”;直接赋值

    特点:

    ​  此时字符串abc是存在字符串常量池中的。

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

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


  • new出来的字符串

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

    String s1 = new String(“abc”);

    String s2 = “abc”;

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

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


2.5 String内存讲解

2.5.1 字符串池(StringTable)

  • StringTable(串池)在JDK7版本开始从方法区中挪到了堆内存,用来保存若干个字符串的地址值;
  • 字符串池当中绝对不会出现重复的字符串所对应的地址
  • 凡是直接双引号赋值的字符串默认在字符串池中,而new出来的字符串默认不在字符串池中
  • 当使用双引号“”直接赋值时,系统会检查该字符串在串池中是否存在
    • 不存在:创建新的
    • 存在:复用

如下图:

  一开始串池里面没有abc这个字符串,所以会先创建abc字符串,并将这个字符串的地址值赋给s1;随后abc这个字符串就在字符串池中,s2赋值时,就不需要再创建abc字符串对象,直接复用字符串池中abc的地址就行,到达节约内存的目的。

在这里插入图片描述

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

在这里插入图片描述


2.6 字符串的比较

2.6.1 ==号的作用

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

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


2.6.2 equals方法的作用

  • 方法介绍

    比较两个字符串内容是否相同区分大小写

    public boolean equals(String s)     //比较两个字符串内容是否相同、区分大小写
    
  • 示例代码

    public class StringDemo02 {
          
          
        public static void main(String[] args) {
          
          
            //构造方法的方式得到对象,new出来的地址字不一样
            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);//false,地址不一样
            System.out.println(s1 == s3);//false,地址不一样
            System.out.println(1==2);//false,数据值不一样
            System.out.println(s3 == s4);//true,地址一样,字符串池中
            System.out.println("--------");
    
            //比较字符串内容是否相同
            System.out.println(s1.equals(s2));//true,内容一样
            System.out.println(s1.equals(s3));//true,内容一样
            System.out.println(s3.equals(s4));//true,内容一样
        }
    }
    

2.6.3 equalsIgnoreCase方法的使用

  • 方法介绍

    比较两个字符串内容是否相同、忽略大小写

public boolean equalsIgnoreCase(String anotherString) //将此 String 与另一个 String 比较,不考虑大小写。 
  • 示例代码:
        //比较字符串对象中的内容是否相等,忽略大小写
        //1 一 壹 这不行
        //忽略大小写只能是英文状态下的a A
        System.out.println("abc".equalsIgnoreCase("ABC"));//true,只能英文单词
        System.out.println("1".equalsIgnoreCase("一"));//false,汉字不行
        System.out.println("1".equalsIgnoreCase("壹"));//false

2.6.4 键盘输入字符串的细节

通过一步步查看源码可知道,键盘输入的字符串最终是new出来的

查看源码:

ctrl+B 或者按着ctrl键不松,鼠标点击对应方法名即可。

示例代码:

 public static void main(String[] args) {
    
    
        //1.假设我现在键盘录入一个abc
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str1 = sc.next();//abc  是new出来的。
        //2.代码中再定义一个字符串abc
        String str2 = "abc";
        //3.用==比较,这两者能一样吗?
        System.out.println(str1 == str2);//false

        //结论:
        //以后只要想比较字符串的内容,就必须要用String里面的方法
    }

2.7 用户登录案例

2.7.1 案例需求

​ 已知用户名和密码,请用程序实现模拟用户登录。总共给三次机会,登录之后,给出相应的提示


2.7.2 代码实现

public class Test1登录案例 {
    
    
    public static void main(String[] args) {
    
    
        //1.定义两个变量用来记录正确的用户名和密码
        String rightUsername = "thanks";
        String rightPassword = "1234qwer";

        //2.键盘录入用户名和密码
        //ctrl + alt + T 选择包裹方式

        for (int i = 0; i < 3; i++) {
    
    //0 1 2
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入用户名");
            String username = sc.next();
            System.out.println("请输入密码");
            String password = sc.next();

            //3.判断比较
            if (username.equals(rightUsername) && password.equals(rightPassword)) {
    
    
                System.out.println("登录成功");
                //如果正确,循环结束
                break;
            } else {
    
    
                //最后一次机会
                if(i == 2){
    
    
                    System.out.println("账户" + username + "被锁定,请联系官方小姐姐:XXXXXXX");
                }else{
    
    
                    //不是最后一次机会
                    System.out.println("用户名或密码错误,登录失败,还剩下" + (2 - i) + "次机会");//2 1 0
                }
            }
        }

    }
}


2.8 遍历字符串案例

2.8.1 案例需求

​ 键盘录入一个字符串,使用程序实现在控制台遍历该字符串。

char charAt(int index) ;// 返回指定索引处的 char 值。 
int length() ;// 返回此字符串的长度。 

2.8.2 直接遍历字符串

public class Test2字符串直接遍历 {
    
    
    public static void main(String[] args) {
    
    
        //两个方法:
        //charAt():会根据索引获取对应的字符
        //length(): 会返回字符串的长度


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

        //2.遍历
        for (int i = 0; i < str.length(); i++) {
    
    
            //i 依次表示字符串的每一个索引
            //索引的范围:0 ~  长度-1

            //根据索引获取字符串里面的每一个字符
            //ctrl + alt + V 自动生成左边的接受变量
            char c = str.charAt(i);
            System.out.println(c);
        }
    }
}


2.9 统计字符次数案例

2.9.1 案例需求

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


2.9.2 代码实现

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++) {
    
    
            //i 表示字符串中的索引
            //c 表示字符串中的每一个字符
            char c = str.charAt(i);

            //对c进行判断,char类型的变量在参与计算的时候自动类型提升为int 查询ascii码表
            if (c >= 'a' && c <= 'z') {
    
      //也可以实用ASCII码进行比较48,65,97
                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 + "个");
    }
}


2.10 字符串拼接案例

2.10.1 案例需求

​ 定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,

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


2.10.2 代码实现

public class Test5数组拼接成字符串 {
    
    
    public static void main(String[] args) {
    
    
        //定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,
        //并在控制台输出结果。例如,数组为 int[] arr = {1,2,3};
        //执行方法后的输出结果为:[1, 2, 3]


        int[] arr = {
    
    1, 2, 3, 4, 5};

        String str = arrToString(arr);
        System.out.println(str);

    }


    //作用:把一个数组变成字符串
    public static String arrToString(int[] arr) {
    
    
        String s = "";
        //拼接左括号
        s = s + "["; //此时是拿着长度为0的字符串,跟[进行拼接,产生一个新的字符串。
        //把新的字符串再赋值给s,此时变量s记录的就是新的字符串"["的地址值

        //下面我想得到数组里面的每一个元素并进行拼接
        //那么就需要遍历数组,得到每一个元素才行
        for (int i = 0; i < arr.length; i++) {
    
    
            //假设第一次循环:i = 0 获取的就是0索引上的元素
            //在拼接的时候:"[" + 1 + ", " 拼接完毕之后产生一个新的字符串 "[1, "
            //第二次循环:i = 1 获取的就是1索引上的元素
            //在拼接的时候: 此时s就是第一次循环结束后拼接完毕的结果:"[1, "
            //在拼接的时候:"[1, " + 2 + ", " 拼接完毕之后产生一个新的字符串 "[1, 2, "
            //...
           if(i == arr.length - 1){
    
    
               //如果是最后一个元素,那么不需要拼接逗号空格
               s = s + arr[i]+"]";
           }else{
    
    
               //如果不是最后一个元素,需要拼接元素和逗号空格
               s = s + arr[i] + ", ";
           }
        }

        //等循环结束之后,再拼接最后一个右括号
        // s = s + "]";

        return s;

    }


    //用来遍历数组
    public static void printArr(int[] arr) {
    
    
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
    
    
            if (i == arr.length - 1) {
    
    
                System.out.print(arr[i]);
            } else {
    
    
                System.out.print(arr[i] + ", ");
            }
        }
        System.out.println("]");

        //[1, 2, 3, 4, 5]
        //我们现在要知道,这个最终结果是怎么来的?
        //从到右依次打印得来的。
    }
}


2.11 字符串反转案例

2.11.1 案例需求

​ 定义一个方法,实现字符串反转。键盘录入一个字符串,调用该方法后,在控制台输出结果

​ 例如,键盘录入 abc,输出结果 cba


2.11.2 代码实现

public class Test6反转字符串 {
    
    
    public static void main(String[] args) {
    
    
        /*定义一个方法,实现字符串反转。键盘录入一个字符串,调用该方法后,在控制台输出结果
        例如,键盘录入 abc,输出结果 cba*/


        //1.定义一个字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str = sc.next();
        //2.定义一个方法,反转字符串
        //abc  --->  cba
        //可以把字符串倒着遍历,再拼接
        String result = reverse(str);
        System.out.println(result);


    }

    //注释:方法的作用就是反转字符串
    //把传递进来的字符串进行反转
    public static String reverse(String str){
    
    //abc
        //核心思想:倒着遍历并进行拼接就可以了
        //fori :正着遍历  forr:倒着遍历
        String s = "";
        for (int i = str.length() - 1; i >= 0; i--) {
    
    
            //i 依次表示字符串里面的每一个索引(倒着的)
            //我们就可以拿到里面的每一个字符并拼接
            s = s + str.charAt(i);
        }

        //把倒着拼接之后的结果返回即可
        return s;

    }
}


2.12 金额转换

2.12.1 案例需求

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

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


2.12.2 代码实现

import java.util.Scanner;

public class StringDemo9 {
    
    
    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 (money != 0) {
    
    
            //从右往左获取数据,因为右侧是数据的个位
            int ge = money % 10;
            String capitalNumber = getCapitalNumber(ge);
            //把转换之后的大写拼接到moneyStr当中
            moneyStr = capitalNumber + moneyStr;
            //第一次循环 : "伍" + "" = "伍"
            //第二次循环 : "叁" + "伍" = "叁伍"
            //去掉末尾
            money = money / 10;
        }

        //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) {
    
    
        //定义数组,让数字跟大写的中文产生一个对应关系
        //这种思想相比if对每一个进行判断简便得多
        String[] arr = {
    
    "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
        //返回结果
        return arr[number];
    }

}


2.13 手机号屏蔽

2.13.1 案例需求

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

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

 String substring(int beginIndex);//返回一个新的字符串,它是此字符串的一个子字符串。 
 String substring(int beginIndex, int endIndex) ;//返回一个新字符串,它是此字符串的一个子字符串。 

包头不包尾,包左不包右; 返回值是截取的子字符串

2.13.2 代码实现

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

    }
}


2.14 敏感词替换

 String replace(char oldChar, char newChar) 
          返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 
 String replace(CharSequence target, CharSequence replacement) 
          使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。 
 String replaceAll(String regex, String replacement) 
          使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 
 String replaceFirst(String regex, String replacement) 
          使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 

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

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:如果要替换的敏感词比较多怎么办?

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);//后裔你玩什么啊,***,***,***,***

    }
}


2.15 身份证信息查看

2.15.1 案例需求

身份证的每一位都是有固定的含义:

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

要求打印内容方式如下:

​ 人物信息为:

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

​ 性别为:男/女


2.15.2 代码实现

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("性别为:男");
        }*/

        //int genderNum = (int)gender;  //强制转换
        
        //但是char类型计算时会自动转换为int,就可以不强转   
        if(genderNum % 2 == 0){
    
    
            //偶数是女
            System.out.println("性别为:女");
        }else{
    
    
            System.out.println("性别为:男");
        }
    }
}

2.16 String常用方法总结

2.16.1 方法引入

 char charAt(int index) 
          返回指定索引处的 char 值。 
    
 int compareTo(String anotherString) 
          按字典顺序比较两个字符串。
 int compareToIgnoreCase(String str) 
          按字典顺序比较两个字符串,不考虑大小写。 
    
 String concat(String str) 
          将指定字符串连接到此字符串的结尾。 
    
 static String copyValueOf(char[] data) 
          返回指定数组中表示该字符序列的 String。   数组变成字符
 static String copyValueOf(char[] data, int offset, int count) 
          返回指定数组中表示该字符序列的 String。   包头不包尾
    
 char[] toCharArray() 
          将此字符串转换为一个新的字符数组。
    
 boolean startsWith(String prefix) 
          测试此字符串是否以指定的前缀开始。 
 boolean startsWith(String prefix, int toffset) 
          测试此字符串从指定索引开始的子字符串是否以指定前缀开始。 
 boolean endsWith(String suffix) 
          测试此字符串是否以指定的后缀结束。 
    
 boolean equals(Object anObject) 
          将此字符串与指定的对象比较。 
 boolean equalsIgnoreCase(String anotherString) 
          将此 String 与另一个 String 比较,不考虑大小写。 
  
 int length() 
          返回此字符串的长度
 boolean isEmpty() 
          当且仅当 length()0 时返回 trueint indexOf(int ch) 
          返回指定字符在此字符串中第一次出现处的索引。 
 int indexOf(String str) 
          返回指定子字符串在此字符串中第一次出现处的索引。 
 int lastIndexOf(int ch) 
          返回指定字符在此字符串中最后一次出现处的索引。 
 int lastIndexOf(String str) 
          返回指定子字符串在此字符串中最后一次出现处的索引。  
 
 String replace(char oldChar, char newChar) 
          返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 
    
 String[] split(String regex) 
          根据给定正则表达式的匹配拆分此字符串。 
 String[] split(String regex, int limit) 
          根据匹配给定的正则表达式来拆分此字符串。 

 String substring(int beginIndex) 
          返回一个新的字符串,它是此字符串的一个子字符串。 
 String substring(int beginIndex, int endIndex) 
          返回一个新字符串,它是此字符串的一个子字符串。 
    
 
 String toLowerCase() 
          使用默认语言环境的规则将此 String 中的所有字符都转换为小写。 
 String toUpperCase() 
          使用默认语言环境的规则将此 String 中的所有字符都转换为大写。 
    
 String trim() 
          返回字符串的副本,忽略前导空白和尾部空白。 
     
 static String valueOf(boolean b) 
          返回 boolean 参数的字符串表示形式。 
 static String valueOf(char c) 
          返回 char 参数的字符串表示形式。 
 static String valueOf(char[] data) 
          返回 char 数组参数的字符串表示形式。 
 static String valueOf(char[] data, int offset, int count) 
          返回 char 数组参数的特定子数组的字符串表示形式。 
 static String valueOf(double d) 
          返回 double 参数的字符串表示形式。 
 static String valueOf(float f) 
          返回 float 参数的字符串表示形式。 
 static String valueOf(int i) 
          返回 int 参数的字符串表示形式。 
 static String valueOf(long l) 
          返回 long 参数的字符串表示形式。 
 static String valueOf(Object obj) 
          返回 Object 参数的字符串表示形式。 

2.16.2 代码实现

public class StringAllMethod {
    
    
    public static void main(String[] args) {
    
    
        //1. 返回指定索引处的 char 值。
        System.out.println("ABCDefg".charAt(2)); //C

        //2. 按字典顺序比较两个字符串。
        System.out.println("d".compareTo("a"));//68-65=3
        System.out.println("d".compareToIgnoreCase("C"));//1

        //3. 将指定字符串连接到此字符串的结尾。拼接字符串
        System.out.println("123".concat("ABC"));//123ABC

        //4.将字符数组转换成字符串
        char[] chars = {
    
    'a','b','c','d','e'};
        System.out.println(String.copyValueOf(chars));//abcde
        System.out.println(String.copyValueOf(chars,0,2));//ab

        //5.将字符串转换成字符数组
        char[] chars1 = "abcdefg".toCharArray();
        for (int i = 0; i < chars1.length; i++) {
    
    
            System.out.print(chars1[i]+" "); //a b c d e f g
        }
        //再将字符数组转换成字符串
        String string = new String(chars1);//abcdefg
        System.out.println(string);

        //6.是否以指定的前缀开始,后缀结束
        System.out.println("abc666cde".startsWith("abc"));//true
        System.out.println("abc666cde".startsWith("6",3));//true
        System.out.println("abc666cde".endsWith("de"));//true

        //7.字符串内容比较
        System.out.println("abc".equals("ABC"));//false
        System.out.println("abc".equalsIgnoreCase("ABC"));//true

        //8.返回此字符串的长度
        System.out.println("123456".length());//6

        //9. 判断字符串长度是否为0
        System.out.println("".isEmpty());//true

        //10.返回第一次出现的索引,没找到返回-1
        System.out.println("123456".indexOf('2'));//1
        System.out.println("123456".indexOf("456"));//3

        //11.返回最后一次出现的索引,没找到返回-1
        System.out.println("abcabc".lastIndexOf('b'));//4
        System.out.println("abcabc".lastIndexOf("abc"));//3

        //12.替换字符串
        System.out.println("后羿,sb".replace("sb","失败"));//后羿,失败

        //13.字符串分隔
        String str = "1,,2,3,4,,,," ;
        String[] splitArr = str.split(",");//按照逗号分隔
        for (int i = 0; i < splitArr.length; i++) {
    
    
            //第二个逗号作为空字符串在字符串数组中存在,而字符串str末尾的逗号都被舍弃。
            System.out.print(splitArr[i]+"~");//1~~2~3~4~
        }
        System.out.println();

        //14.截取子串,包头不包尾
        System.out.println("511236202212026789".substring(6));//202212026789
        System.out.println("511236202212026789".substring(6,14));//20221202

        //15.(所有字符)大小写转换
        System.out.println("AbC".toUpperCase()); //ABC
        System.out.println("aBc".toLowerCase()); //abc

        //16.去掉首尾空白
        System.out.println("   hoW are you !     ".trim());//hoW are you !

        //17.将其他数据类型转换成String类型
        String s = String.valueOf(33.3);  //33.3
        String s1 = String.valueOf(67 + 9);//76
        String s2 = String.valueOf('a');//a
        String s3 = String.valueOf(true);//true
        String s4 = s+s1+s2+s3;
        System.out.println(s+"\n"+s1+"\n"+s2+"\n"+s3+"\n"+s4);//33.376atrue
    }

}


3.StringBuilder

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

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

  • 作用:提高字符串的操作效率

3.1 构造方法

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

3.2 常用方法

方法名 说说明
public StringBiulder append(任意类型) 添加数据,并返回对象本身
public StringBiulder reverse() 反转容器中的内容
public int length() 返回长度(字符出现的个数)
public String toString() 通过toString()就可以实现把StringBuilder转换为String
public int capacity() 返回当前容量。容量指可用于最新插入字符的存储量,超过这一容量便需要再次分配。
public StringBuilder delete(int start, int end) 移除此序列的子字符串中的字符,包左不包右
public StringBuilder deleteCharAt(int index) 移除此序列指定位置上的 char。
StringBuilder insert(int offset, char c) 将 char 参数的字符串表示形式插入此序列中。

3.3 String、StringBiulder对比

public class StringBuilderDemo1 {
    
    
    /*使用String运行太慢了,半天不出结果*/
    
    public static void main(String[] args) {
    
    
        String s = "";
        for (int i = 0; i < 1000000; i++) {
    
    
            s = s + "abc";
        }
        System.out.println(s);
    }
}




public class StringBuilderDemo2 {
    
    
    /*StringBiuler快多了,秒出结果*/
    
    public static void main(String[] args) {
    
    
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < 1000000; i++) {
    
    
            sb.append("abc");
        }

        System.out.println(sb);
    }
}


3.4 基本使用

public class StringBuilderDemo3 {
    
    
    public static void main(String[] args) {
    
    
        //1.创建对象
        StringBuilder sb = new StringBuilder("abc");

        //2.添加元素
       /*sb.append(1);
        sb.append(2.3);
        sb.append(true);*/
        
        //链式编程思想
        sb.append(1).append(2.3).append(true).append(true);
        

        //3.打印
        //普及:
        //因为StringBuilder是Java已经写好的类
        //java在底层对他做了一些特殊处理。
        //打印对象不是地址值而是属性值。
        //就可以直接打印
        System.out.println(sb);//abc12.3true

        //4.反转
        sb.reverse();
        System.out.println(sb);//eurt3.21cba

        //5.获取长度
        int len = sb.length();
        System.out.println(len);//11
        
            
        //6.变回String
        //StringBuilder仅仅是一个容器,用完了之后将他变回String,才可以操作String对应的方法
        String s = sb.toString();
        System.out.println(s);//eurt3.21cba
        
        //7.删除
        System.out.println(sb.delete(4, 8));  //删掉索引[4,8)的字符,eurtcba
        System.out.println(sb.deleteCharAt(2));  //删掉索引为2的字符,eutcba

        //8.插入
        System.out.println(sb.insert(0, 123));//插入,123eutcba
        System.out.println(sb.insert(0, 'a'));//插入,a123eutcba
        System.out.println(sb.insert(0, "666"));//插入,666a123eutcba
        
    }
}

3.5 链式编程

public class StringBuilderDemo5 {
    
    
    public static void main(String[] args) {
    
    
        //链式编程:
        //当我们在调用一个方法的时候,不需要用变量接收他的结果,可以继续调用其他方法
        int len = getString().substring(1).replace("A", "Q").length();
        System.out.println(len);
    }
    
    public static String getString(){
    
    
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str = sc.next();
        return str;
    }
}

3.6 练习1:对称字符串

需求:

​ 键盘接受一个字符串,程序判断出该字符串是否是对称字符串,并在控制台打印是或不是

对称字符串:123321、111

非对称字符串:123123

代码示例:

public class StringBuilderDemo6 {
    
    
    //使用StringBuilder的场景:
    //1.字符串的拼接
    //2.字符串的反转

    public static void main(String[] args) {
    
    
        //1.键盘录入一个字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str = sc.next();

        //2.反转键盘录入的字符串,最后记得toString
        String result = new StringBuilder(str).reverse().toString();

        //3.比较
        if(str.equals(result)){
    
    
            System.out.println("当前字符串是对称字符串");
        }else{
    
    
            System.out.println("当前字符串不是对称字符串");
        }

    }
}


3.7 练习2:拼接字符串

需求:定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回。

​ 调用该方法,并在控制台输出结果。

​ 例如:数组为int[] arr = {1,2,3};

​ 执行方法后的输出结果为:[1, 2, 3]

代码示例:

public class StringBuilderDemo7 {
    
    
    public static void main(String[] args) {
    
    
        //1.定义数组
        int[] arr = {
    
    1,2,3};

        //2.调用方法把数组变成字符串
        String str = arrToString(arr);

        System.out.println(str);

    }


    public static String arrToString(int[] arr){
    
    
        StringBuilder sb = new StringBuilder();
        sb.append("[");

        for (int i = 0; i < arr.length; i++) {
    
    
            if(i == arr.length - 1){
    
    
                sb.append(arr[i]);
            }else{
    
    
                sb.append(arr[i]).append(", ");
            }
        }
        sb.append("]");

        return sb.toString();
    }
}


4. StringJoiner

  • StringJoiner跟StringBuilder一样,也可以看成是一个容器,创建之后里面的内容是可变的
  • 作用:提高字符串的操作效率,而且代码编写特别简洁,但是目前市场上很少有人用。
  • JDK8出现的

4.1 构造方法

方法名 说明
public StringJoiner(间隔符号) 创建一个StringJoiner对象,指定拼接时的间隔符号
public StringJoiner(间隔符号,开始符号,结束符号) 创建一个StringJoiner对象,指定拼接时的间隔符号、开始符号、结束符号

4.2 常用方法

方法名 说明
public StringJoiner add (添加的内容) 添加数据,并返回对象本身
public int length() 返回长度(字符出现的个数)
public String toString() 返回一个字符串(该字符串就是拼接之后的结果)

4.3 基本使用

//1.创建一个对象,并指定中间的间隔符号
StringJoiner sj = new StringJoiner("---");
//2.添加元素
sj.add("aaa").add("bbb").add("ccc");
//3.打印结果
System.out.println(sj);//aaa---bbb---ccc


StringJoiner sj2 = new StringJoiner(", ","[","]");
sj2.add("aaa").add("bbb").add("ccc");
//4.返回长度
int len = sj2.length();
System.out.println(len);//15  计算了开始符号结束符号间隔符号

System.out.println(sj2);//[aaa, bbb, ccc]
//5.返回一个字符串(
String str = sj2.toString();
System.out.println(str);//[aaa, bbb, ccc]

5. 三个字符串类的区别

  1. String

    表示字符串的类,定义了很多操作字符串的方法

  2. StringBuilder
    一个可变的操作字符串的容器。

    可以高效的拼接字符串,还可以将容器里面的内容反转

  3. StringJoiner
    JDK8出现的一个可变的操作字符串的容器,可以高效,方便的拼接字符串。在拼接的时候,可以指定间隔符号,开始符号,结束符号。


# 6. 字符串原理

6.1 字符串拼接的底层原理

6.1.1 没有出现变量

拼接的时候没有变量,都是字符串,触发字符串的优化机制,在编译的时候就已经是最终的结果了。

在这里插入图片描述


6.1.2 出现了变量

  • jdk8以前

    系统底层会自动创建一个StringBuilder对象,然后再调用其append方法完成拼接。
    拼接后,再调用其toString方法转换为String类型,而toString方法的底层是直接new了一个字符串对象。

在这里插入图片描述

在这里插入图片描述

  • jdk8以后的优化

    系统会预估要字符串拼接之后的总大小,把要拼接的内容都放在数组中,此时也是产生一个新的字符串

在这里插入图片描述


6.1.3 StringBuilder提高效率原理图

在这里插入图片描述


6.2 常见面试题

只要有变量参与就是创建了一个的字符串。

在这里插入图片描述

public class test7 {
    
    
    public static void main(String[] args) {
    
    
        String str1 = "abc";
        String str2 = "abc";
        String str3 = "ab";
        String str4 = str3 + "c";

        System.out.println(str1 == str2);//true   都在池中
        System.out.println(str1 == str4);//false  有变量参与,就是创建一个新的字符串
        System.out.println(str2 == str4);//false

    }
}

没有变量参与

在这里插入图片描述


6.3 字符串原理小结

6.3.1 字符串存储的内存原理

  • 直接赋值会复用字符串常量池中的
  • new出来不会复用,而是开辟一个新的空间

6.3.2 ==号比较的到底是什么?

  • 基本数据类型比较数据值
  • 引用数据类型比较地址值

6.3.3 字符串拼接的底层原理

如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串。

如果有变量参与,每一行拼接的代码,都会在内存中创建新的字符串,浪费内存。


6.3.4 StringBuilder提高效率原理

所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存。


6.3.5 StringBuilder源码分析

默认创建一个长度为16的字节数组

添加的内容长度小于16,直接存

添加的内容大于16会扩容(原来的容量*2+2)(16*2+2=34)

如果扩容之后还不够,容量等于实际长度

public class capacity {
    
    
    public static void main(String[] args) {
    
    
        StringBuilder sb = new StringBuilder();
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        StringBuilder sb3 = new StringBuilder();
        StringBuilder sb4 = new StringBuilder();
        //容量:最多装多少
        //长度:已经装多少
        System.out.println(sb.capacity());//16
        System.out.println(sb.length());//0

        sb.append("abcdefg");
        System.out.println(sb.capacity());//16
        System.out.println(sb.length());//7

        sb1.append("abcdefghijklmnopqrstuywxyz");
        System.out.println(sb1.capacity());   //扩容:16*2+2=34
        System.out.println(sb1.length());//26

        sb2.append("abcdefghijklmnopqrstuywxyz0123456789");
        System.out.println(sb2.capacity());  //36,扩容(34)之后还不够,容量等于实际长度
        System.out.println(sb2.length());//36

    }
}


7. 练习

练习一:转换罗马数字

键盘录入一个字符串,

要求1:长度为小于等于9

要求2:只能是数字将内容变成罗马数字

下面是阿拉伯数字跟罗马数字的对比关系:

l - 1、 - 2、- 3、IV - 4、V - 5、VI- 6、VII - 7、vIl - 8、IX - 9

注意点:

罗马数字里面是没有0的

如果键盘录入的数字包含0,可以变成””(长度为0的字符串)

方法一

package com.thk.test;

import java.util.Scanner;

public class Test1Case1 {
    
    
    public static void main(String[] args) {
    
    
       /* 键盘录入一个字符串,
        要求1:长度为小于等于9
        要求2:只能是数字
                将内容变成罗马数字
        下面是阿拉伯数字跟罗马数字的对比关系:
        Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9
        注意点:
        罗马数字里面是没有0的
        如果键盘录入的数字包含0,可以变成""(长度为0的字符串)*/


        //1.键盘录入一个字符串
        Scanner sc = new Scanner(System.in);
        String str;
        while (true) {
    
    
            System.out.println("请输入一个字符串");
            str = sc.next();
            //2.校验字符串是否满足规则
            boolean flag = checkStr(str);
            if (flag) {
    
    
                break;
            } else {
    
    
                System.out.println("当前的字符串不符合规则,请重新输入");
                continue;  //continue要位于循环中
            }
        }

        //将内容变成罗马数字
        //下面是阿拉伯数字跟罗马数字的对比关系:
        //Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9
        //查表法:数字跟数据产生一个对应关系
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
    
    
            char c = str.charAt(i);
            int number = c - 48; // 1 2 3 4 5,或者使用强转,亦或是: c-'0' 更好记忆
            String s = changeLuoMa(number);
            sb.append(s);
        }

        System.out.println(sb);
    }
    
    

    /**
     * 数字对应表
     *
     * @param number
     * @return
     */
    public static String changeLuoMa(int number) {
    
    
        //定义一个数组,让索引跟罗马数字产生一个对应关系
        String[] arr = {
    
    "", "Ⅰ", "Ⅱ", "Ⅲ", "Ⅳ", "Ⅴ", "Ⅵ", "Ⅶ", "Ⅷ", "Ⅸ"};
        return arr[number];

    }


    /**
     * 校验输入的字符串
     *
     * @param str
     * @return
     */
    public static boolean checkStr(String str) {
    
    //123456
        //要求1:长度为小于等于9
        if (str.length() > 9) {
    
    
            return false;
        }
        //要求2:只能是数字
        for (int i = 0; i < str.length(); i++) {
    
    
            //取的每一个字符
            char c = str.charAt(i);//0~9
            if (c < '0' || c > '9') {
    
    
                return false;
            }
        }
        //只有当字符串里面所有的字符全都判断完毕了,我才能认为当前的字符串是符合规则
        return true;
    }

}

方法二

package com.thk.test;

import java.util.Scanner;

public class Test1Case2 {
    
    
    public static void main(String[] args) {
    
    
       /* 键盘录入一个字符串,
        要求1:长度为小于等于9
        要求2:只能是数字
                将内容变成罗马数字
        下面是阿拉伯数字跟罗马数字的对比关系:
        Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9
        注意点:
        罗马数字里面是没有0的
        如果键盘录入的数字包含0,可以变成""(长度为0的字符串)*/


        //1.键盘录入一个字符串
        //书写Scanner的代码
        Scanner sc = new Scanner(System.in);
        String str;
        while (true) {
    
    
            System.out.println("请输入一个字符串");
            str = sc.next();
            //2.校验字符串是否满足规则
            boolean flag = checkStr(str);
            if (flag) {
    
    
                break;
            } else {
    
    
                System.out.println("当前的字符串不符合规则,请重新输入");
                continue;
            }
        }

        //将内容变成罗马数字
        //下面是阿拉伯数字跟罗马数字的对比关系:
        //Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9
        //查表法:数字跟数据产生一个对应关系
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
    
    
            char c = str.charAt(i);
            String s = changeLuoMa(c);  //直接传递字符
            sb.append(s);
        }

        System.out.println(sb);
    }



    /**
     * 利用switch进行匹配,Java 12的switch甚至可作为表达式了——不再是单独的语句
     * @param number
     * @return
     */
    public static String changeLuoMa(char number) {
    
    
/*        String str = switch (number) {
            case '0' -> "";
            case '1' -> "Ⅰ";
            case '2' -> "Ⅱ";
            case '3' -> "Ⅲ";
            case '4' -> "Ⅳ";
            case '5' -> "Ⅴ";
            case '6' -> "Ⅵ";
            case '7' -> "Ⅶ";
            case '8' -> "Ⅷ";
            case '9' -> "Ⅸ";
            default -> str = "";
        };*/

        String str;
        switch (number){
    
    
            case '0':
                str = "";
                break;
            case '1':
                str = "Ⅰ";
                break;
            case '2':
                str = "Ⅱ";
                break;
            case '3':
                str = "Ⅲ";
                break;
            case '4':
                str = "Ⅳ";
                break;
            case '5':
                str = "Ⅴ";
                break;
            case '6':
                str = "Ⅵ";
                break;
            case '7':
                str = "Ⅶ";
                break;
            case '8':
                str = "Ⅷ";
                break;
            case '9':
                str = "Ⅸ";
                break;
            default:
                str = "";
                break;
        }
        return str;
    }


    /**
     * 校验输入的字符串
     *
     * @param str
     * @return
     */
    public static boolean checkStr(String str) {
    
    //123456
        //要求1:长度为小于等于9
        if (str.length() > 9) {
    
    
            return false;
        }
        //要求2:只能是数字
        for (int i = 0; i < str.length(); i++) {
    
    
            char c = str.charAt(i);//0~9
            if (c < '0' || c > '9') {
    
    
                return false;
            }
        }
        //只有当字符串里面所有的字符全都判断完毕了,我才能认为当前的字符串是符合规则
        return true;
    }
}

练习二:调整字符串

给定两个字符串,A和B。

A的旋转操作就是将A最左边的字符移动到最右边。

例如,若A= ‘abcde’,在移动一次之后结果就是’bcdea’。如果在若干次调整操作之后,A 能变成B,那么返回True。如果不能匹配成功,则返回false

方法一

public class Test2Case1 {
    
    
    public static void main(String[] args) {
    
    
       /* 给定两个字符串, A和B。
        A的旋转操作就是将A 最左边的字符移动到最右边。
        例如, 若A = 'abcde',在移动一次之后结果就是'bcdea'
        如果在若干次调整操作之后,A能变成B,那么返回True。
        如果不能匹配成功,则返回false*/

        //1.定义两个字符串
        String strA = "abcde";
        String strB = "cdeab";

        //2.调用方法进行比较
        boolean result = check(strA, strB);

        //3.输出
        System.out.println(result);


    }

    /**
     * 验证两个字符串
     * @param strA
     * @param strB
     * @return
     */
    public static boolean check(String strA, String strB) {
    
    
        //1.abcde   >  bcdea
        //2.bcdea   >  cdeab
        //3.cdeab   >  deabc
        //4.deabc   >  eabcd
        //5.eabcd   >  abcde
        //6.abcde   
        //所以:循环上限次数就是字符串的长度
        for (int i = 0; i < strA.length(); i++) {
    
    
            strA = rotate(strA);  //返回的值依旧用自身接收,不用其他变量!!!
            if(strA.equals(strB)){
    
    
                return true;
            }
        }
        //所有的情况都比较完毕了,还不一样那么直接返回false
        return false;
    }



    /**
     * 作用:旋转字符串,把左侧的字符移动到右侧去
     * 形参:旋转前的字符串
     * 返回值:旋转后的字符串
     * @param str
     * @return
     */
    public static String rotate(String str) {
    
    
        //套路:
        //如果我们看到要修改字符串的内容
        //可以有两个办法:
        //1.用subString进行截取,把左边的字符截取出来拼接到右侧去
        //2.可以把字符串先变成一个字符数组,然后调整字符数组里面数据,最后再把字符数组变成字符串。

        //截取思路
        //获取最左侧那个字符
        char first = str.charAt(0);
        //获取剩余的字符
        String end = str.substring(1);

        return end + first;
    }
}

方法二

public class Test2Case2 {
    public static void main(String[] args) {
       /* 给定两个字符串, A和B。
        A的旋转操作就是将A 最左边的字符移动到最右边。
        例如, 若A = 'abcde',在移动一次之后结果就是'bcdea'
        如果在若干次调整操作之后,A能变成B,那么返回True。
        如果不能匹配成功,则返回false*/

        //1.定义两个字符串
        String strA = "abcde";
        String strB = "cdeab";

        //2.调用方法进行比较
        boolean result = check(strA, strB);

        //3.输出
        System.out.println(result);
    }


    /**
     * 验证两个字符串
     * @param strA
     * @param strB
     * @return
     */
    public static boolean check(String strA, String strB) {
        for (int i = 0; i < strA.length(); i++) {
            strA = rotate(strA);
            if (strA.equals(strB)) {
                return true;
            }
        }
        //所有的情况都比较完毕了,还不一样那么直接返回false
        return false;
    }


    /**
     * 作用:旋转字符串,把左侧的字符移动到右侧去
     * 形参:旋转前的字符串
     * 返回值:旋转后的字符串
     * @param str
     * @return
     */
    public static String rotate(String str) {
        //套路:
        //如果我们看到要修改字符串的内容
        //可以有两个办法:
        //1.用subString进行截取,把左边的字符截取出来拼接到右侧去
        //2.可以把字符串先变成一个字符数组,然后调整字符数组里面数据,最后再把字符数组变成字符串。

        //可以把字符串先变成一个字符数组,然后调整字符数组里面数据,最后再把字符数组变成字符串。


        //"ABC"   ['A','B','C']  ['B','C','A']   new String(字符数组);
        char[] arr = str.toCharArray();
        //拿到0索引上的字符
        char first = arr[0];
        //把剩余的字符依次往前挪一个位置
        for (int i = 1; i < arr.length; i++) {
            arr[i - 1] = arr[i];
        }
        //把原来0索引上的字符放到最后一个索引
        arr[arr.length - 1] = first;

        //利用字符数组创建一个字符串对象!!!
        String result = new String(arr);
        return result;
    }
}

练习三:打乱字符串

import java.util.Random;
import java.util.Scanner;

public class Test3 {
    
    
    public static void main(String[] args) {
    
    
        //键盘输入任意字符串,打乱里面的内容

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

        //2.打乱里面的内容
        //修改字符串里面的内容:
        //1.subString  本题不好用
        //2.变成字符数组
        char[] arr = str.toCharArray();

        //3.打乱数组里面的内容
        //从0索引开始,跟一个随机索引进行位置的交换
        //当数组里面的每一个元素都跟一个随机索引进行交换完毕之后,那么内容就打乱了
        Random random = new Random();
        for (int i = 0; i < arr.length; i++) {
    
    
            int index = random.nextInt(arr.length);
            char temp = arr[i];
            arr[i] = arr[index];
            arr[index] = temp;
        }

        //4.把字符数组再变回字符串
        String result = new String(arr);
        System.out.println(result);
    }
}

练习四:生成验证码

内容:

​ 可以是小写字母,也可以是大写字母,还可以是数字

规则:

​ 长度为5

​ 内容中是四位字母,1位数字。

​ 其中数字只有1位,但是可以出现在任意的位置。

import java.util.Random;

public class Test4 {
    
    
    public static void main(String[] args) {
    
    
       /*
        生成验证码
        内容:可以是小写字母,也可以是大写字母,还可以是数字
        规则:
        长度为5
        内容中是四位字母,1位数字。
        其中数字只有1位,但是可以出现在任意的位置。*/

        //1.可以把所有的大写字母,小写字母都放到一个数组当中
        char[] arr = new char[52];
        // A-Z  a-z
        for (int i = 0; i < 26; i++) {
    
    
            arr[i] = (char)(i+65);  //存大写
            arr[i+26] = (char)(i+97);  //存小写
        }

        //2.从数组中随机获取4次
        StringBuilder sb =new StringBuilder();
        Random r = new Random();
        for (int i = 0; i < 4; i++) {
    
    
            int index = r.nextInt(arr.length);
            sb.append(arr[index]);  //拼接字符串
        }

        //3.生成一个0~9之间的随机数拼接到最后
        int num = r.nextInt(10);

        //4.将这个整数转换为字符串形式,在拼接到sb最后
        //sb.append(String.valueOf(i)) ;
        //源码有:
        // public StringBuilder append(int i) {
    
    
        //        super.append(i);
        //        return this;
        //    }
        //所以可以直接添加,不需要将其先转换为字符形式
        sb.append(num) ;
//        System.out.println(sb);

        //5.把生成的验证码先变成一个字符数组
        char[] result = sb.toString().toCharArray();
        //打乱数组元素
        for (int i = 0; i < result.length; i++) {
    
    
            int index = r.nextInt(result.length);
            char temp = arr[i];
            arr[i] = arr[index];
            arr[index] = temp;
        }

        //6.把字符数组再变回字符串形式
        String resultStr = new String(result);
        System.out.println(resultStr);
    }
}

练习五:字符串乘积

给定两个以字符串形式表示的非负整数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。

方法一

public class Test5Case1 {
    
    
    public static void main(String[] args) {
    
    
        /* 给定两个以字符串形式表示的非负整数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。
        注意:需要用已有的知识完成。*/

        //不需要考虑乘积过大之后的结果
        //就认为乘积一定是小于int的最大值的


        String str1 = "3658";
        String str2 = "123";

        //1.把num1和num2变成对应的整数,使用包装类方法
        int num1 = Integer.parseInt(str1);
        int num2 = Integer.parseInt(str2);

        //2.将整数转换成字符串形式
        System.out.println(String.valueOf(num1 * num2));


    }
}

方法二

public class Test5Case2 {
    
    
    public static void main(String[] args) {
    
    
        /* 给定两个以字符串形式表示的非负整数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。
        注意:需要用已有的知识完成。*/

        //不需要考虑乘积过大之后的结果
        //就认为乘积一定是小于int的最大值的

        //1.定义两个字符串
        String str1 = "100";
        String str2 = "200";

        //2.将字符转换为整数,并计算结果,并将结果表示为字符串形式
        int ret = getInt(str1) * getInt(str2);
        System.out.println("乘积是:"+String.valueOf(ret));
    }

    /**
     * 数据表
     * @param number
     */
    private static int dataTable(int number) {
    
    
        int[] num = {
    
    0,1,2,3,4,5,6,7,8,9};
        return num[number];
    }

    /**
     * 字符串转换为整数
     * @param str
     * @return
     */
    private static int getInt(String str){
    
    
        int number = 0;
        for (int i = 0; i < str.length(); i++) {
    
    
            //str1.charAt(i)-48:取下字符并-48的ASCII码值
            //通过dataTable()得到对应的整型数字
            number =number *10 + dataTable((str.charAt(i)-48));
        }
        return number;
    }
}

练习六:计算最后一个单词长度

给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中最后一个单词的长度。

单词是指仅由字母组成、不包含任何空格字符的最大子字符串。

​ 示例 1:输入:s = "Hello World“ 输出:5

​ 解释:最后一个单词是“World”,长度为5。

​ 示例 2:输入:s = " fly me to the moon" 输出:4

​ 解释:最后一个单词是“moon”,长度为4。

​ 示例 3:输入:s = “luffy is still joyboy” 输出:6

​ 解释:最后一个单词是长度为6的“joyboy”。

public class Test6 {
    
    
    public static void main(String[] args) {
    
    
        //倒着遍历
        //直到遇到空格为止

        String str1 = "Hello World   ";
        String str2 = "   fly me   to   the moon   ";
        String str3 = "luffy is still joyboy   ";

        //trim()去掉首尾多余的空格
        System.out.println("str1:"+str1+"\n"+"最后一个单词的长度"+getLastWordLength(str1.trim()));
        System.out.println("str2:"+str2+"\n"+"最后一个单词的长度"+getLastWordLength(str2.trim()));
        System.out.println("str3:"+str3+"\n"+"最后一个单词的长度"+getLastWordLength(str3.trim()));

    }

    /**
     * 返回字符串中最后一个单词的长度
     * @param str
     */
    private static int getLastWordLength(String str) {
    
    
        //1.使用计数器
        int count  = 0;

        //2.将数组转换成字符数组
        char[] chars = str.toCharArray();
        for (int i = chars.length - 1; i >= 0; i--) {
    
    
            if(chars[i] != ' '){
    
    
                count++;
            }else{
    
    
                break;
            }
//            System.out.print(chars[i]+" ");
        }
        return count;

    }
}

猜你喜欢

转载自blog.csdn.net/qq_53139964/article/details/128162729