Java巅峰之路---基础篇---字符串

目录

字符串学习内容

String

概述

注意点

创建String对象的两种方式

直接比较内容的两个方法

例题

StringBuilder

概述

 适用场景以及注意事项

创建StringBuilder对象

例题

StringJonier

 概述

注意事项

创建StringJonier对象

 例题

知识点

substring(参数)方法

replace(参数)方法

实际开发中的一些常见案例

用户登录

金额转换 

 手机号屏蔽

身份证信息查看 

敏感词替换

字符串相关的底层原理

扩展底层原理1:字符串存储的内存原理

扩展底层原理2:==号比较的到底是什么?

扩展底层原理3:字符串拼接的底层原理

扩展底层原理4:StringBuilder提高效率原理图

 扩展底层原理5:StringBuilder源码分析

总结


字符串学习内容

String

概述

java.lang.String类代表字符串,Java程序中的所有字符串文字(例如“abc”)都为此类的对象。

注意点

字符串的内容是不会发生改变的,他的对象在创建后不能被更改

String name = "aaa";
name = "bbb";

这两段代码中,"bbb"是创建了一个新的字符串对象,然后再赋值给变量name,但"aaa"并没有被改变,这个过程中一共产生了两个字符串

创建String对象的两种方式

1、直接赋值:String name = "俊熙";

2、new String(参数):



​        String s = new String();
        String s1 = new String("abc");
        char[] ch = {'a','b','c'};//字符数组
        String s2 = new String(ch);//根据字符数组的内容再创建一个新的字符串对象
        byte[] bytes  = {97,98,99,100};//字节数组
        String s3 = new String(bytes);//根据字节数组的(ASCII转换后)内容再创建一个新的字符串对象
        System.out.println("a" + s + "b");//ab
        System.out.println(s1);//abc
        System.out.println(s2);//abc
        System.out.println(s3);//abcd

​

直接比较内容的两个方法

· boolean equals方法(要比较的字符串)        完全一样结果才是true,否则为false

· boolean equalsIgnoreCase(要比较的字符串)        忽略大小写的比较

        String s1 = new String("abc");
        String s2 = "abc";
        String s3 = "Abc";
        
        System.out.println(s1 == s2);//false

        //直接比较内容
        System.out.println(s1.equals(s2));//true
        //直接比较内容(忽略大小写)
        System.out.println(s1.equalsIgnoreCase(s3));//true

例题

字符串的反转 

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

思路:运用左右指针的思想对s的字符数组char[] ch进行操作就行,最后返回new String(ch)。

    public static void main(String[] args) {
        String s1 = "sbcdefg";
        char[] ch = s1.toCharArray();//得到s1对应的字符数组
        System.out.println(reverse(ch));

    }
    public static String reverse(char[] ch){
        int left = 0,right = ch.length - 1;
        while(left < right){
            char tmp = ch[left];
            ch[left] = ch[right];
            ch[right] = tmp;
            left++;
            right--;
        }
        return new String(ch);
    }

StringBuilder

概述

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

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

 适用场景以及注意事项

适用场景:字符串的反转和拼接

注意:因为StringBuilder是Java已经写好的类,在底层对其做了一些特殊处理,打印对象不是地址值,而是属性值

创建StringBuilder对象

构造方法

常用方法

例题

对称字符串

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

对称字符串:123321、111

非对称字符串:123123

    public static void main(String[] args) {
        //1、接受一个字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String s = sc.next();
        //2、将字符串反转(链式编程)
        String result = new StringBuilder(s).reverse().toString();

        //3、字符串比较
        boolean flag = result.equals(s);
        if (flag) {
            System.out.println(s + "是对称字符串");
        }else {
            System.out.println(s +" 不是对称字符串");
        }
    }

StringJonier

 概述

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

作用:提高字符串的操作效率,而且代码编写特别简洁,但是用的人较少

注意事项

StringJonier该方法没有无参构造,使用add方法时只能添加字符串。

创建StringJonier对象

 成员方法

 例题

    public static void main(String[] args) {
        StringJoiner sj1 = new StringJoiner("");
        sj1.add("aaa").add("123");
        System.out.println(sj1.toString());//aaa123

        StringJoiner sj2 = new StringJoiner("," , "[" ,"]");
        sj2.add("aaa").add("bbb").add("ccc");
        System.out.println(sj2);//[aaa,bbb,ccc]
    }

知识点

substring(参数)方法

· String substring(int beginIndex, int endIndex) 截取

注意:包头不包尾,包左不包右;只有返回值才会截取的小串

· String substring(int beginIndex) 截取(重载方法,从该位置截取到末尾)

        String s = "qeqfw";

        System.out.println(s.substring(0,2));//qe
        System.out.println(s.substring(2));//qfw
        System.out.println(s);//qeqfw

replace(参数)方法

· String replace(旧值,新值) 替换

注意点:只有返回值才是替换之后的结果

        String s = "afdaf";
        System.out.println(s.replace('a','b'));//bfdbf
        System.out.println(s);//afdaf

实际开发中的一些常见案例

用户登录

需求:

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

思路:首先定义正确的用户名和密码,然后写出用户登录过程的业务逻辑,最后在加上个for循环即可。

        String username = "zhangsan";
        String password = "zs181855";
        Scanner sc = new Scanner(System.in);

        //比较,给三次机会
        for (int i = 0; i < 3; i++) {
            System.out.println("请输入用户名");
            String inputusername = sc.next();
            System.out.println("请输入密码");
            String inputpassword = sc.next();
            if (username.equals(inputusername) && password.equals(inputpassword)) {
                System.out.println("用户登录成功");
                break;
            } else {
                if (i==2) System.out.println("账号"+username + "被锁定,请联系相关客服解决");
                else System.out.println("用户名或密码错误," + "你还剩" + (2 - i) + "次机会,请重新输入");
            }
        }

金额转换 

用户输入一位整数,将其变成大写。例如:2135-->零佰零拾零万贰仟壹佰叁拾伍元

思路:

    public static void main(String[] args) {

        //键盘录入一个金额
        Scanner sc = new Scanner(System.in);
        int money;
        while(true){
            System.out.println("请输入七位数的金额");
            money = sc.nextInt();
            if(money >= 0 && money < 10000000){
                break;
            }else System.out.println("金额无效");
        }

        //将数字变成大写中文
        String s = "";
        while(money != 0){
            int n = money % 10;
            s  = transform(n) + s;
            money /= 10;
        }

        //将零补齐
        int end = 7 - s.length();
        for (int i = 0; i < end; i++) {
            s = '零' + s;
        }

        //添加单位
        char[] ch = {'佰', '拾', '万', '仟', '佰', '拾', '元'};

        String result = "";
        for(int i = 0; i < ch.length; i++)
            result += String.valueOf(s.charAt(i)) + String.valueOf(ch[i]);
        System.out.println(result);
    }
    //定义一个方法,将数字转化为大写
    public static char transform(int num){
        char[] ch = {'零', '壹',  '贰',  '叁',  '肆',  '伍',  '陆',  '柒',  '捌',  '玖'};
        return ch[num];
    }

 手机号屏蔽

 代码:

        String phoneNumber = "12345678901";

        String start = phoneNumber.substring(0,3);

        String end = phoneNumber.substring(7);

        System.out.println(start + "****" + end);

身份证信息查看 

根据给定的身份证号,输出一下人物信息

    public static void main(String[] args) {
        //1、给出一个身份证号,得出对应的信息
        String user = "450111197205054878";
        //截取第7~14位以及第十七位的数字
        String year = user.substring(6,10);
        String month = user.substring(10,12);
        String day = user.substring(12,14);
        char c = user.charAt(16);
        //2.打印出生年月日
        System.out.println("人物信息为:");
        System.out.println("出生年月日:"  + year + "年"+ month + "月"+ day + "日");
        //3.判断性别
        int number = c - 48;//将 '3'->3
        if(number % 2 ==0){
            System.out.println("性别为:女");
        }else {
            System.out.println("性别为:男");
        }
    }

敏感词替换

        String talk = "你玩的真好,以后就不要再玩了,TMD,CNM";

        String[] arr = {"TMD","CNM", "SB" ,"MLGB"};

        //循环得到数组中的每一个敏感词,依此进行替换
        for(int i = 0; i < arr.length; i++){
            talk = talk.replace(arr[i] , "***");
        }

        System.out.println(talk);//你玩的真好,以后就不要再玩了,***,***

字符串相关的底层原理

扩展底层原理1:字符串存储的内存原理

内存模型 

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

 当使用的是new String(参数)时,每new一次就是在堆内存开辟了一个新的小空间,地址空间肯定不会相同

扩展底层原理2:==号比较的到底是什么?

所以,使用双引号直接赋值s1和s2,在s1和s2的内容相等是,比较的结果就是true;除此之外,其他任何情况用==号来比较时,返回的都是false

扩展底层原理3:字符串拼接的底层原理

这里就直接总结了:

· 如果没有变量参与

都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串

· 如果有变量参与

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

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

都会在内存中创建新的字符串,浪费内存

· 结论

如果很多字符串变量拼接,不要直接+。在底层会创建多个对象,浪费时间,浪费性能。

扩展底层原理4:StringBuilder提高效率原理图

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

 扩展底层原理5:StringBuilder源码分析

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

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

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

· 如果扩容之后还不够,以实际长度为准

总结

1、直接赋值字符串,首先会在串池里边找,如果有,则复用;否则,会在串池中创建一个。

2、直接比较内容的两个方法:equals(参数)以及equalsIgnoreCase(参数)。

3、StringBuilder可以看成是一个容器,创建之后里面的内容是可变的,主要适用于字符串的拼接;此外,StringJonier于StringBuilder差不多,但其可以在添加的字符串之间以及头尾“加上一些符号”。

4、介绍了substring(参数)方法以及replace(参数)方法。

5、实际开发中一些小案例以及字符串的底层原理。

  • 36
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值