Java学习笔记8.——字符串以及底层原理(案例练习)

Java学习笔记8.——字符串

Java学习笔记8.——字符串



前言

这节讲了字符串的比较,拼接,创建的底层原理,以及常用的几种String方法和对象。
比如STringBuilder对象,StringJoiner对象,这个对象是jdk8以后出现的。
replace方法,charAt方法,subString方法。


一、API

api(Application Programming Interface):应用程序编程接口。
官方写好封装好的东西,我们可以直接使用不需要自己编写。
官方也提供了jdk_api帮助文档,可以在网上下载使用。

二、String

字符串和任何东西拼接都是字符串。

“123”+“456” = “123456”
“321”+true = “321true”
“技术”+200 = “技术200”

1.字符串被创建后其值就不能被改变,看着赋的值也是新的字符串。

  • 这就和引用型的原理是一样的。赋的新值字符串想到于在堆区创建了新的空间,原来的对象指向了新的空间地址。

2.字符串是java定义好的类,在java.lang中,使用时不需要再导包
3.所有字符串文字都是此包的对象

String name = "专注技术200年";
name = "厚德载物";

这上面就是创建了两个字符串,只是name指向了新的字符串地址。

1.String两种赋值方式

String字符串有两种方式,第二种方式在api帮助文档里也能找到。

public static void main(String[] args) {
        //1.直接赋值
        String s1 = "abc";
        System.out.println(s1);

        //2.使用new方式创建
        //1.空参构造方法,这种没啥必要,输出什么也没有
        String s2 = new String();
        System.out.println(s2);

        //2.使用有参构造方法,也没必要,类似于创建数组一样
        String s3 = new String("abc");
        System.out.println(s3);

        //3.使用字符数组为参数构造,这种用于改变某一个单词的时候
        char[] c = {'a','b','c','d'};
        String s4 = new String(c);
        System.out.println(s4);

        //4.使用字节数组为参数构造,//用于网络传数据的时候
        byte[] b = {97,98,99,100};
        String s5 = new String(b);
        System.out.println(s5);

    }

2.String内存

在之前学过了栈,方法运行时进栈,运行完就出栈。
堆区,使用new关键字时就会在堆区创建新的空间
方法区,字节码文件(.class)进入方法区临时存储
现在学串池,以前在方法区中,现在在堆区中

  • 直接赋值的可以在串池中寻找。
    • 若是没有该值则在串池中新建一个,把地址值传过去。
    • 如果有该值则可以直接复用。
  • 使用new创建的则是在堆区中创建。
    • 比如上面的char数组,在堆区中创建了一个数组,把地址值赋给c,然后s4使用new关键字创建了一个字符串,这个字符串的地址是新开辟的空间地址。如果再创建一个字符串s6,使用同样的方式创建,那么这个s6的地址值也是一个新的空间开辟的地址值。
      可以对比看出不会复用,只会创建新的空间
      在这里插入图片描述
      到现在算是有了些大概的了解了。

3.String字符串的比较

比较实用等于符号来比较的。

  • 基本数据类型 == 比较的是具体的值
  • 引用型数据类型 == 比较的是具体的地址值,而不是里面的值
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);

//案例2
String s3 = new String("abc");
System.out.println(s1 == s3);//false

刚刚说过,引用型数据类型比较值是比较地址值,s1与s2都是直接赋值使用的是串池中的,s2是复用s1开辟的地址值,所以s1和s2的地址值一样,结果是true;
s3的创建类型是new方式,所以其地址值在堆区中而不在串池区,所以和s1的地址值不一样,结果为false

难道想比较字符串的具体值内容(不是地址值)就不可以了吗?
所以java官方提供了两种方法。
equls() 比较内容
equlsIgnoreCase()比较内容,忽略大小写

String s1 = "abc";
        String s12 = "ABc";
        System.out.println(s1==s12);
        System.out.println(s12);

String s3 = new String("abc");
        System.out.println(s3);
        boolean result = s3.equals(s1);
        boolean result2 = s3.equalsIgnoreCase(s12);
        System.out.println(result);
        System.out.println(result2);

所以键盘输入的字符串也可以用equals方法进行比较内容,那地址值的话根据底层逻辑发现也是new出来的一个空间,所以与直接赋值或者new的字符串用==符号不相等,结果为false。

三、案例

1.用户登录

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

package String;

import java.util.Scanner;

public class Test2 {
    public static void main(String[] args) {
//        用户登录
//需求:已知正确的用户名和密码,请用程序实现模拟用户登录。
//总共给三次机会,登录之后,给出相应的提示

        //1.先确定正确的用户名和密码,自己设置。
        String name = "user";
        String passwd = "987654321";
        //2.用户键盘录入用户名和密码
        Scanner sc = new Scanner(System.in);
        boolean flag = true;
        //3.录入之后比较用户名和密码的值,用equals
        // 4.可以有三次密码输错的机会,只要有1次就可以登录成功就可以。
        for (int i = 0; i < 3; i++) {
            System.out.println("请输入用户名");
            String sname = sc.next();
            System.out.println("请输入密码");
            String spwd = sc.next();

            boolean nresult = name.equals(sname);
            boolean presult = passwd.equals(spwd);
            if (nresult && presult){
                System.out.println("登录成功!!!");
                flag = false;
                break;
            }else {
                System.out.println("用户名或者密码错误,请重新登录");
            }
        }

        if (flag){
            System.out.println("今日三次机会已用完,请明日再试");
        }
    }
}

2.遍历字符串

charAt(int index)这个方法根据索引值位置返回字符串的内容
如果s1.charAt(0)则是从首位开始返回字符串内容,这里索引为0也是字符串也有索引,每一个字符都有一个索引位置.
length()因为数组中长度是属性,但是这里是方法所以有括号

public static void main(String[] args) {
        //1.从键盘录入一个字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入任意个字符");
        String s1 = sc.next();
        //2.遍历字符串使用charat
//        s1.charAt(0);
        for (int i = 0; i < s1.length(); i++) {
            System.out.print(s1.charAt(i)+" ");
        }
        //3.length()长度,数组中长度是属性没有括号,这里长度是方法所以有括号
    }

3.统计字符

录入一个字符串,分别统计大小写字母和数字的出现次数,其他字符也统计。
这个点我忘了ASCII码值,可以直接使用’a’这样也代表是正确的,不用专门去把字符改成数字,知道具体的值就可以了。

或许可以把之强制转成int整型判断然后再转成字符型

package String;

import java.util.Scanner;

public class StringTest4 {
    public static void main(String[] args) {
        //1.键盘录入一个字符
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串,只能包含英文字母和数字");
        String s1 = sc.next();
        //2.比较字符产中的大小写字母,和数字出现的次数
        //遍历出字符串中的字符放进数组里面。
        char[] c = new char[s1.length()];
        for (int i = 0; i < c.length; i++) {
            c[i] = s1.charAt(i);
        }

        //使用count三个变量统计次数
        int charcount1 = 0;
        int charcount2 = 0;
        int numcount = 0;
        int count= 0;

        // 使用字符判断大小写和数字
        for (int i = 0; i < c.length; i++) {
            if (c[i] >= 'a' && c[i] <= 'z'){
                charcount1++;
            }else if (c[i] >= 'A' && c[i] <= 'Z'){
                charcount2++;
            }else if (c[i] >= '0' && c[i] <= '9'){
                numcount++;
            }else {
                count++;
            }
        }
        System.out.println(charcount1+" "+charcount2+" "+numcount);
        System.out.println("其他字符:"+count);
    }
}

4.拼接字符串

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

package String;

public class StringTest5 {
    public static void main(String[] args) {
//        拼接字符串
//定义一个方法,把 int数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。
//例如:
//数组为int[]arr = {1,2,3};
//执行方法后的输出结果为:[1,2,3]
        //1.定义1个方法
        int[] arr = null;
        if (arr!=null){//需要考虑到数组的多种情况
            System.out.println(motage(arr));
        }
        //2.需要数组,然后拼接
    }
    public static String motage(int[] arr){
        String s = "[";
        for (int i = 0; i < arr.length; i++) {
            s = s + arr[i];
            if (i<= arr.length -2){
                s = s + ",";
            }
        }
        s = s + "]";
        return s;
    }
}

5.反转字符串

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

package String;

import java.util.Scanner;

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

    public static char[] toArr(){
        //1.录入一个字符串
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        //2.把字符串放进数组,用charAt,因为字符串是由一个个字符串起来的,所以这里使用字符数组
        char[] arr = new char[s.length()];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = s.charAt(i);
        }
//        arr[0] = s.charAt(0);
        //3.把数组反转,然后输出来
        char temp ;
        for (int i = 0,j= arr.length-1; i<j; i++,j--) {
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]);
        }
        return arr;
    }
}

6.数字转换

把2135元变成这种 零佰零拾零万贰仟壹佰叁拾伍元
这个考到了charAt()方法以及字符拼接

package String;

public class StringTest7 {
    public static void main(String[] args) {
        String s1 = "2135";
        //如果数字长度小于等于7就可以依次填上去

        //1.取出字符,比较对应的数字对应中文
        char c ;
        String s2 = "";
        //少几个长度就在前面加几个零
        int length = 7-s1.length();
        for (int i = 0; i < length; i++) {
            s2 = s2 +"零";
        }
        System.out.println(s2);
        for (int i = 0; i <= s1.length()-1; i++) {
            c = s1.charAt(i);
            switch (c){
                case '0':
                   s2 = s2 + "零";
                   break;
                case '1':
                    s2 = s2 + "壹";
                    break;
                case '2':
                    s2 = s2 + "贰";
                    break;
                case '3':
                    s2 = s2 + "叁";
                    break;
                case '4':
                    s2 = s2 + "肆";
                    break;
                case '5':
                    s2 = s2 + "伍";
                    break;
                case '6':
                    s2 = s2 + "陆";
                    break;
                case '7':
                    s2 = s2 + "柒";
                    break;
                case '8':
                    s2 = s2 + "捌";
                    break;
                case '9':
                    s2 = s2 + "玖";
                    break;
            }

        }
        System.out.println(s2);
        String[] s3 = {"佰","拾","万","仟","佰","拾","元"};

        String s4 = "";
        for (int i = 0; i < s2.length(); i++) {
            s4 = s4 + s2.charAt(i)+s3[i];
        }
        System.out.println(s4);
    }
}

因为金额是数字不是字符串,所以可以使用数字取个位数的方法放进数组或者字符串里,后续步骤都是一样的。

7.手机号屏蔽subString()

使用索引和拼接,数组
String subString(int beginIndex,int endIndex),左闭右开区间
String subString(int beginindex),从这个位置截取到末尾

package String;

public class StringTest8 {
    public static void main(String[] args) {
        //手机号屏蔽
        //1.手机号长度11位,前面三位,后面四位显示,中间四位用*显示,用字符串装
        String s1 = "12345678901";
        String s2 = "";
        char integer[] = new char[s1.length()];

        //2.使用charAt,并且判断在哪一位这里可以用数组索引
        for (int i = 0; i < s1.length(); i++) {
            integer[i] = s1.charAt(i);
        }
        for (int i = 0; i < integer.length; i++) {
            if ((i<=2&&i>=0)||(i<=10&&i>=7)){
                s2 = s2+integer[i];
            }else{
                s2 = s2+"*";
            }
        }
        System.out.println(s2);
    }
}

输出结果:123****8901

8.根据身份证输出年月日,性别

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

package String;

public class StringTest9 {
    public static void main(String[] args) {
//        1、2位:省份
//3、4位:城市
//5、6位:区县
//7-14位:出生年、月、日
//15、16位:所在地派出所
//17位:性别(奇数男性,偶数女性)
//18位:个人信息码(随机产生)
        String s = "500229200103270213";
        String s1 = s.substring(6,10);
        s1 = s1 + "年"+ s.substring(10,12);
        s1 = s1 + "月" + s.substring(12,14) +"日";
        System.out.println("人物信息为:");
        System.out.println("出生年月日:"+s1);

        char s2 = s.charAt(17);
        if (s2%2==0){
            System.out.println("性别为:女");
        }else {
            System.out.println("性别为:男");
        }

    }
}

9.关键词屏蔽,replace()

replace(旧值,新值) 替换

public class StringTest10 {
    public static void main(String[] args) {
        //替换敏感词
        String s = "12jo,fojwei,jfSBe,jfoweTMDjfoawej";
        String[] arr = {"TMD","TNND","SB","CNMD"};
        for (int i = 0; i < arr.length; i++) {
            s = s.replace(arr[i], "***");
        }
        System.out.println(s);
    }
}

四、综合知识

1.StringBuilder

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

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

适用于拼接和反转的时候

前面我们知道字符串的内容创建之后是不可以修改的,赋值一个新的字符串也是创建了一个新的空间赋值的地址值。
所以上面案例中很多拼接都是创建的新的字符串,并不是真的拼接成一个了。如果要拼接多个字符串,从1拼接到1000000那就需要拼接即创建这么多字符串,效率低下,所以可以使用StringBuilder这个,因为他创建之后里面的内容可变,没有新增空间创建新的字符串,是在原来空间里操作的。

StringBuilder有两种方法构造方法,有参和无参

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

StringBuilder的常见4种方法

方法名说明
public StringBuilder append(任意类型)添加数据,并返回对象本身
public StringBuilder reverse()反转容器中的内容
public int length()返回长度(字符出现的个数)
public String toString()通过toString()就可以实现把StringBuilder对象转换为String字符串
(有)public StringBuilder delete(int start,int end)删除数据,左闭右开区间,但是0-大于sb数据长度也能删除成功不报错(我使用的IDEA)
StringBuilder stringBuilder = new StringBuilder("123456789");
        System.out.println(stringBuilder);

这里以为输出来的会是StringBuilder 对象地址,但是结果是具体值。
打印对象不是地址值,是属性值。
百度了一下不是很懂,打印的是StringBuilder 对象的内存地址,而不是变量本身的地址。且System.out.println()方法内部会调用toString()方法将对象转换为字符串。这个先暂时保留。

1.对称字符串

    public static void main(String[] args) {
        //对称字符串
//        String s = "123321";
//        StringBuilder sb = new StringBuilder(s);
//        sb.reverse();
//        boolean equals = sb.toString().equals(s);
//        System.out.println(equals);

        StringBuilder sb1 = new StringBuilder("12");
        StringBuilder sb2 = new StringBuilder("12");
        boolean equals = sb1.equals(sb2);
        System.out.println(equals);

注释部分没有问题,就是下面我发现使用equals不能使他们两个的内容相同…我去看了下api开发文档,没有StringBuilder比较相同内容的方法,我猜可能是我这个落后了,也有可能是没有必要,因为他只是字符串的使用工具,最后都是为字符串服务所以没必要。

2.拼接字符串

package String;

public class StringTest12 {
    public static void main(String[] args) {
//        拼接字符串
//需求:定义一个方法,把 int数组中的数据按照指定的格式拼接成一个字符串返回。
//调用该方法,并在控制台输出结果。
//例如:数组为int[]arr = {1,2,3};执行方法后的输出结果为:[1,2,3]
        int[] arr = {1,2,3};
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < arr.length; i++) {
            if (i< arr.length-1){
                sb.append(arr[i]).append(",");
            }else {
                sb.append(arr[i]);
            }
        }
        sb.append("]");
        System.out.println(sb.toString());
    }
}

2.StringJoiner

也可以看出一个容器,里面的内容也是可变的。

  • 作用:提高字符串的操作效率,而且代码简洁
  • 出现于jdk8

构造方法

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

感觉就是比StringBuilder多了个间隔符号的作用,然后没有空参构造

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

五、字符串底层原理

1.字符串拼接

刚刚了解了那么多字符串拼接,也使用了字符串拼接的方法和对象,最终到底都躲不过那个提高字符串操作效率。

1.没有变量拼接

String s = "abc";
String s1 = "a"+"b"+"c";
System.out.println(s==s1);

拼接的时候没有变量,都是字符串会触发字符串的优化机制(常量池里面创建),在编译的时候就已经是最终结果了。

假如常量池里有abc,则直接复用这个字符串。所以结果为true。

2.有变量拼接

String s1 = "a";
String s2 = s1 + "b";
String s3 = s2 + "c";

1.mian方法进栈,s1时在串池中创建“a”
2.s2时串池中创建“b”,此时堆区中创建了new StringBuilder()对象,里面放了“ab”,然后使用toString变成字符串,再把值返回给s2.
3.s3时,串池中创建“c”,并且堆区中会再次创建一个new StringBuilder()对象,里面放了“abc”,然后使用toString变成字符串,再把值返回给s3.
最后发现一个加号两个对象,多占空间啊。

3.jdk8字符串拼接的底层原理

String s1 = "a";
String s2 = "b";
String s3 = "c";
String s4 = s1 + s2 + s3 + s4;

它会先预估字符串的长度有多长,创建一个数组然后再把数填进去再变成字符串。
如果也有变量参与,也会在内存中创建很多对象浪费空间,时间也非常慢,所以以后还是尽量不要有变量参与,尽量不要用+的方式。

jdk8以前:系统底层自动创建一个StringBuilder对象,然后再调用append方法完成拼接。拼接之后调用toString方法转换为String类型,而toString方法的底层源码是直接new了一个字符串对象。
jdk8以后:系统会预估要字符串拼接之后的大小,把拼的内容放进数组中此时也产生了一个新的字符串…

2.StringBuilder提高效率

所有拼接的内容都会放在StringBuilder中,是可变内容,所以不会创建很多无用的空间,节约内存。

容量,长度区别(银行卡中长度为9,但是能放的金额很多几千上百亿都能装下),StringBuilder的长度就是int的范围那么大

public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        System.out.println(sb.capacity());
        System.out.println(sb.length());
        sb.append("abcdefghijklmnopqrstuvwxyz");
        System.out.println(sb.capacity());
        System.out.println(sb.length());
        sb.append("abcdefghijklmnopqrstuvwxyz1234567890");
        System.out.println(sb.capacity());
        System.out.println(sb.length());
    }
扩容1:每次扩容的时候都是老容量*2 + 2 = 34
public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        System.out.println(sb.capacity());
        System.out.println(sb.length());
        sb.append("abcdefghijklmnopqrstuvwxyz1234567890");
        System.out.println(sb.capacity());
        System.out.println(sb.length());
    }
扩容2:如果超出*2+2的容量则以实际容量为准 = 36,长度也36,16+20(20是超出的部分。)
public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        System.out.println(sb.capacity());
        System.out.println(sb.length());
        sb.append("abcdefghijklmnopqrstuvwxyz1234567890");
        System.out.println(sb.capacity());
        System.out.println(sb.length());
        sb.append("abcdefghijklmnopqrstuvwxyz1234567890111");
        System.out.println(sb.capacity());
        System.out.println(sb.length());
    }

可以连续扩容

1.转换罗马数字

转换罗马数字
键盘录入一个字符串,要求1∶长度为小于等于9要求2:只能是数字将内容变成罗马数字
下面是阿拉伯数字跟罗马数字的对比关系:
l - 1、ll - 2、II - 3、IV - 4、V - 5、VlI-6、VII - 7、VI -8、IX - 9注意点:
罗马数字里面是没有0的 如果键盘录入的数字包含0,可以变成””(长度为0的字符串)

public static void main(String[] args) {
        //转换罗马数字
        //键盘录入一个字符串,要求1∶长度为小于等于9要求2:只能是数字将内容变成罗马数字
        //下面是阿拉伯数字跟罗马数字的对比关系:
        //l - 1、ll - 2、II - 3、IV - 4、V - 5、VlI-6、VII - 7、VI -8、IX - 9注意点:
        //罗马数字里面是没有0的  如果键盘录入的数字包含0,可以变成””(长度为0的字符串)
        //1.录入字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入长度小于9的数字");
        String s1 = sc.next();
        //2.判断长度小于等于9
        convert(s1);
        //3.将数字变成罗马数字,replace(旧值,新值)替换

    }
    //3.将数字变成罗马数字,replace(旧值,新值)替换
    public static void convert(String s1){
        String[] number = {"0","1","2","3","4","5","6","7","8","9"};
        String[] luoma = {"","I","II","III","IV","V","VI","VII","VIII","IX"};
        for (int i = 0; i < number.length; i++) {
            s1 = s1.replace(number[i], luoma[i]);
        }
        System.out.println(s1);
    }

这个没写完,后面重新写了个其他的方法,这里没有判断数字和长度。(其实我总以为自己判断了,,还是读题有点不严谨)

2.旋转字符

调整字符串
给定两个字符串,A和B。
A的旋转操作就是将A最左边的字符移动到最右边。
例如,若A= ‘abcde’,在移动一次之后结果就是’bcdea’如果在若干次调整操作之后,A能变成B,那么返回True。如果不能匹配成功,则返回false

public static void main(String[] args) {
        //调整字符串
        //给定两个字符串,A和B。
        //A的旋转操作就是将A最左边的字符移动到最右边。
        //例如,若A= 'abcde',在移动一次之后结果就是'bcdea'如果在若干次调整操作之后,A能变成B,那么返回True。如果不能匹配成功,则返回false
        String s1 = "abcde";
        String s2 = "deabc";
        boolean flag = chekStr(s1,s2);
        if (flag){
            System.out.println("匹配成功");
        }else {
            System.out.println("匹配不成功");
        }
    }
    public static boolean chekStr(String s1,String s2){
        String stemp = s1;
        //假如匹配不成功
        boolean flag = false;
        for (int i = 0;i < s2.length();i++) {
            //截取第1位
            String temp1 = stemp.substring(0,1);
            //截取第2位到末尾
            String temp2 = stemp.substring(1);
            //把后面的先添加再添加第1位,这样看起来就像旋转的了,然后转成字符串
            StringBuilder sb = new StringBuilder();
            stemp = sb.append(temp2).append(temp1).toString();
            if (stemp.equals(s2)){
                System.out.println(stemp);
                flag = true;
                break;
            }
        }
        return flag;
    }

还可以用字符数组,调整数据的位置就可以了。

package String;

public class StringTest14Case2 {
    public static void main(String[] args) {
        //调整字符串
        //给定两个字符串,A和B。
        //A的旋转操作就是将A最左边的字符移动到最右边。
        //例如,若A= 'abcde',在移动一次之后结果就是'bcdea'如果在若干次调整操作之后,A能变成B,那么返回True。如果不能匹配成功,则返回false
        String s1 = "abcde";
        String s2 = "deabc";
        boolean flag = false;
        for (int i = 0; i < s2.length(); i++) {
             s1 = chekStr(s1);
            if (s1.equals(s2)){
                System.out.println(s1);
                flag=true;
                break;
            }
        }
        if (flag){
            System.out.println("匹配成功");
        }else {
            System.out.println("匹配失败");
        }
    }
    public static String chekStr(String s1){
        char[] c = s1.toCharArray();
        char first = c[0];
        for (int i = 1; i < c.length; i++) {
            c[i-1] = c[i];
        }
        c[c.length-1]=first;
        String s = new String(c);
        return s;
    }
}

3.把字符串转成数字转成字符串

给定两个以字符串形式表示的非负整数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。注意:需要用已有的知识完成。

ASCII码值,字符串转变成字符数组,字符数组转换成整型数字

package String;

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

        boolean b = chek(s1);
        boolean b2 = chek(s2);
        if (b && b2){
            int num1 = toInt(s1);
            int num2 = toInt(s2);
            StringBuilder sb = new StringBuilder(num1*num2);
            System.out.println(sb);
        }else {
            System.out.println("不是非负整数,字符串不合规则");
        }
        
    }
    public static boolean chek(String s){
        char[] c1 = s.toCharArray();
        for (int i = 0; i < c1.length; i++) {
            if (c1[i]>'9'||c1[i]<'0'){
                return false;
            }
        }
        return true;
    }

    public static int toInt(String s){
        char[] c1 = s.toCharArray();//[1,2,3,4,5,6]
        int num1 = 0 ;
        //把其转为整型,且-48
        for (int i = 0; i < c1.length; i++) {
            num1 = num1*10 + c1[i]-48;
        }
        return num1;
    }
}

4.返回单词

给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。
返回字符串中最后一个单词的长度。
单词是指仅由字母组成、不包含任何空格字符的最大子字符串。
示例1:输入:s = "Hello wor1d“ 输出:5
解释:最后一个单词是"wor1d”,长度为5。
示例2:输入:s = “fly me tothe moon” 输出:4
解释:最后一个单词是"moon”,长度为4。
示例3:输入:s = “luffy is still joyboy” 输出:6
解释:最后一个单词是长度为6的“joyboy”。

   public static void main(String[] args) {
        ///*给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。
        //返回字符串中最后一个单词的长度。
        //单词是指仅由字母组成、不包含任何空格字符的最大子字符串。
        //示例1:输入:s = "Hello wor1d“ 输出:5
        //解释:最后一个单词是"wor1d”,长度为5。
        //示例2:输入:s = "fly me tothe moon" 输出:4
        // 解释:最后一个单词是"moon”,长度为4。
        //示例3:输入:s = "luffy is still joyboy" 输出:6
        //解释:最后一个单词是长度为6的“joyboy”。*/

        StringBuilder sb = new StringBuilder("luffy is still joyboy");
        String s = sb.reverse().toString();
        char[] c = s.toCharArray();
        int count = 0;
        for (int i = 0; i < c.length; i++) {
            if (c[i] == ' '){
                count = i;
                break;
            }
        }
//        String s2 = s.substring(0, count);
//        StringBuilder sb2 = new StringBuilder(s2).reverse();
        System.out.println(count);

    }

总结

  • 1.api开发文档等于java字典
  • 2.String 的两种赋值方式,一个在串池,一个在堆区
  • 3.==比较的内容
    • 基本数据类型比较的具体的值
    • 引用数据类型比较的是地址值
  • 4.String拼接的原理
    • 没有变量参与时,在编译时就完成拼接,(如果串池有拼接好的就是复用串池中的)
    • 有参数时就会在堆区创建StringBuilder对象拼接,然后使用toString变成字符串返回
  • 5.StringBuilder提高字符串操作效率,因为空间内内容可变,不会无故增加新的空间,节约空间
  • 6.STringBuilder的范围与int一样
    • 扩容:老容量*2+2
    • 扩容:如果超过上面,那就是老容量+超出部分的长度,实际容量为准
      只有返回值才是使用后的结果

1.char charAt(int index)
2.String subString(int beginIndex,intendIndex),左闭右开区间
3.String subString(int beginindex),从这个位置截取到末尾
4.replace(旧值,新值) 替换
5.StringBuilder容器,里面的内容可变,提升字符串操作效率
6.StringJoiner(间隔符号),与STringBuilder有些类似,这个在添加时有间隔符号

  • 28
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

专注技术200年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值