第三章Java字符串

在这里插入图片描述

  戳我跳到个人主页

  本人码云(建议pc端打开,手机可能会出现字体过小问题。)
  本人会不定期在码云上更新一些算法或数据结构的基础程序,后期也会学习进阶程序,也会更新大厂的面试题。
  如果您有好的建议和想法,欢迎在本人码云相应代码评论区评论哦。希望大家都能在编程这条路上越走越远。也祝看到这篇博客的人,能真正搞懂这方面知识,当然,若有错误,请提出改正,谢谢大家啦。

  本人后续会在这里更新操作系统和计组的笔记,敬请期待!
  有赞必回,评论必回,顺着网线回访!

引入

JDK中String类的声明:
为何String类被final修饰?

final 修饰的类无法被继承,String类不存在子类。

这样的话就可以保证所有使用JDK的人,大家用到的String类仅此一个,大家都相同。

假设现在String允许继承,每个人都可以继承String类,修改它的方法等实现。MyString1和MyString2、3都是完全不同的子类,都可以向上转型变为String。
String str = new MyString1();
String str = new MyString2();
String str = new MyString3();

假设每个人都扩展、每个人都自己覆写equals方法、那么就会有歧义、从而导致String类使用不统一、因为String是一个非常常见的类、总不能在你的电脑上可以正常运行的代码,在别人那里就不行了,对吧~~

这就说明:继承和方法覆写在带来灵活的同时,也会带来很多子类行为不一致导致的问题。

什么时候会用到 final 修饰类

你希望这个类不要有别的版本,那么就到此为止,所有使用者的这个类完全相同,没有别的实现。

1.创建字符串

方式一:直接赋值
方式二:通过构造方法产生对象
方式三:通过字符数组产生对象
方式四:通过String的静态方法valueOf(任意数据类型)转为字符串
最常用是1 和 4字面量:直接写出来的数值就是字面量

10 int字面量
3.14 double字面量
true boolean字面量
“abc” 字符串字面量
在这里插入图片描述

2.字符串比较相等

所有引用数据类型在比较数值相等时,使用equals方法比较,JDK常用类,都已经覆写了equals方法,直接使用即可。例如:String、Integer
如果是自己写的类,如Student类,Person类等,都要自己覆写equals方法。

引用数据类型如果使用 “==” 运算符、比较的仍然是数值,不过是比较地址值是否相等,地址值代表的是它们在内存、即堆上是否在同一个位置上

在这里插入图片描述

字符串除了比较值相等(equals)、比较地址相等(==)以外,
字符串String也实现了Comparable接口,覆写了compareTo方法
在这里插入图片描述

3.字符串常量池

为什么引用常量池?

所谓的 “ 池 ” – 都是类似的思想
共享设计模式、节省空间(内存是一个紧俏的资源!)
字符串产生之后大部分情况下都是用来进行输出处理、打印它的内容
“hello”,为啥不整一个就行了~
数据库的连接池 线程池都是类似的思想

手工入池方法:String类提供的intern方法
在这里插入图片描述

调用intern方法会将当前字符串引用指向的对象保存到字符串常量池中。
a.若当前常量池中已经存在了该对象,则不再产生新的对象,返回常量池中的String对象地址。
b.若当前常量池中不存在该对象,则将该对象入池,返回入池后的地址。
在这里插入图片描述再比如:
在这里插入图片描述

字符串牵扯用户输入,判空

	//这个变量由用户由浏览器输入
    String userName = null;

    //a
    System.out.println(userName.equals("小树"));
    //b
    System.out.println("小树".equals(userName));
    //哪种方法好?
    //牵扯到用户输入、一定要判空
    //如果采用a方法、userName可能为空
    //用一个null去点一个方法、会产生空指针异常
    //推荐采用b方法、把待比较的特定内容放在前面
    //这样非常好,方便处理userName为空的情况

4.字符串的不可变性

在这里插入图片描述

为何字符串对象无法修改内容,而其他类的对象能修改内容呢?
字符串就是一个字符数组 ==> char[],字符串保存的值实际上在数组中保存
在这里插入图片描述String外部无法访问这个value数组
String并没有提供关于value属性的getter和setter方法
对于String类的外部而言,value数组完全无法使用。
因此字符串对象的内容无法修改(String类的外部拿不到这个value数组)

5.如何修改字符串的内容

a.在运行时通过反射破坏value数组的封装(了解,非常不推荐!ds部分讲反射就会了,反射是所有框架的基础)

在这里插入图片描述

b.更换使用StringBuilder或者StringBuffer类 ==> 已经不是同一个类型了

若需要频繁进行字符串的拼接,使用StringBuilder类的append方法
StringBuilder类可以修改对象的内容。

在这里插入图片描述StringBuffer与StringBuilder使用方法完全一样、但是StringBuffer线程安全、支持多线程、性能较差。

6.StringBuilder类具体使用

StringBuilder和String类是两个独立的类,因为String的对象无法修改内容,为了方便字符串的拼接操作,产生了StringBuilder类。
StringBuilder类的对象是可以修改内容的。
在这里插入图片描述

请解释String、StringBuilder、StringBuffer的区别:

1.String的对象无法修改,俩sb的对象的内容可以修改;
2.StringBuffer是线程安全的操作,性能较差;StringBuilder是线程不安全,性能较高。

关于本节的两个重点:
a.关于字符串常量池以及intern方法的理解问题;
b.理解啥是个字符串不可变;
c.StringBuilder的使用。

7.字符和字符串的转换

字符串的内部实际上就是使用字符数组来存储的。

将字符数组转换为字符串

public String ( char[] ch )
在这里插入图片描述
其实在valueOf内部、和构造方法是一样的。
在这里插入图片描述
那么能不能用toString呢?
对于char[]这个字符数组对象、它的内部没有覆写toString这个方法、所以它是继承了Object的toString方法、返回地址值、所以不太合适。
在这里插入图片描述

将部分字符数组转换为字符串

public String ( char[] value, int offset, int count )
如果count大于了ch.length-1、越界了、会报错
在这里插入图片描述

取出字符串中指定索引的字符

public char charAt( int index )
返回值char类型
在这里插入图片描述

将字符串的内容转为字符数组

public char[] toCharArray()
此时产生了一个新的字符数组,将字符串的内容复制过去。
字符串String对象不可变!!
在这里插入图片描述

isNumber

自己写一个方法:判断某个字符串是否由纯数字组成

public static boolean isNumber( String str )
    {
        //"123" ==> 转为字符数组
        //1.str == > char[]
        char[] data = str.toCharArray();
        //2.循环遍历data中的每个字符,判断这个字符是否是数字字符
        //['0' ... '9']
        for( char c : data )
        {
            if( c < '0' || c > '9' )
                return false; //找反例
        }
        return true;
    }

系统自带的方法:
在这里插入图片描述

8.String常用方法

1.三个布朗

str.contains("world")判断str中是否包含字串"world"
str.startsWith("hello")str是否以指定字符串开头
str.endsWith("world")str是否以指定字符串结尾
这三个返回值都是布朗

代码:
在这里插入图片描述

2.字符串替换操作

public String replaceAll(String regex, String replacement)
替换所有的指定内容
public String replaceFirst(String regex, String replacement)
替换首个内容

代码

public class StringReplace
{
    public static void main(String[] args)
    {
        String str = "wowowowowo";
        System.out.println( str.replaceAll("w","_") );
        System.out.println( str.replaceAll("wo","ha") );
        System.out.println( str.replaceFirst("wo","ha"));
        /*
        此时的修改是否会修改原字符串的内容?
        不会!
        字符串类中所有针对字符串的操作,都是产生了一个新的字符串
        (字符串的不可变性)只有StringBuilder可以修改
         */
        System.out.println(str);

    }
}

3.字符串拆分操作(拆分成字符数组)

public String[] split( String regex ) 全部拆分
public String[] split( String regex, int limit ) 部分拆分

代码

public class StringSplit
{
    public static void main(String[] args)
    {
//        String str = "Hello Java Hello Rocket";
//        String[] data1 = str.split(" ");
//
//        //按照空格将str拆分,拆分后的字符串数组长度为2
//        String[] data2 = str.split(" ", 2);
//
//        System.out.println(Arrays.toString(data1));
//        System.out.println(Arrays.toString(data2));
//        [Hello, Java, Hello, Rocket]
//        [Hello, Java Hello Rocket]

        //Web开发,经常拆分ip地址
        String str = "192.168.1.1";
        String []data = str.split(".");
        System.out.println(Arrays.toString(data));
        //[] 居然没拆成功
        /*
        当按照指定的格式拆分字符串得到了一个空数组
        原因是:
        你的这个格式是个特殊字符,需要转义处理"\\"
         */
        String []data1 = str.split("\\.");
        System.out.println(Arrays.toString(data1));

        //有时候,拆分之后,得到的字符串和原字符串长得一样
        //这是因为,这个字符在原字符串中不存在
        String[] data2 = str.split( ",");
        String str2 = Arrays.toString(data2);

        System.out.println( str2 );//[192.168.1.1]
        //这是将一个字符数组转换为字符串了,当然有两个框
        //就像将数字1转换为字符串还是长这样:1

        System.out.println( str == str2 );
    }
}

4.字符串的截取处理

public String substring( int beginIndex ) 从指定索引截取到结尾
public String substring( int beginIndex, int endIndex) 截取部分内容

左闭右开,包含开头,不包含结束,只要记住截取的字符长度为 end-begin 就行了。

代码
在这里插入图片描述

5.其他常用方法

在这里插入图片描述

使用:
在这里插入图片描述

注意:
在这里插入图片描述
既然不能用,那么怎么判断一个字符串是否是空或者是null呢?

if( str == null || str.isEmpty() )
    return true;

6.练习

写一个方法,将一个字符串的首字母大写,并返回
方法:

public static String firstUpper(String str)
    {
        //1.判空
        if(str == null || str.isEmpty())
            return null;

        //2.边界
        if(str.length() == 1)
            return str.toUpperCase();

        //3.str长度大于1
        //其实就是一个截取 + 大写操作
        return str.substring(0,1).toUpperCase() + str.substring(1);
    }

应用:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_小树

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

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

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

打赏作者

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

抵扣说明:

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

余额充值