String类

引子

在上古时代,阿涛还在更新C语言的时候给兄弟们说过,在C语言中只有字符类,没有字符串类型,我们都是使用char *指针指向字符串,但是时代变了,在Java中String也是非常重要的知识点。

写字符串

我们之前说的只要是“ ”起来的内容,都是字符串,经过一段时间的学习,单纯这样理解是远远不够的。

        char[]arr={'a','a','f'};
        String str=new String("dhhiqhdi");
        String str1="adad";
        String str2=new String(arr);

常用的构建字符串的方法就在上面了。

品String

Java作为面向对象的主流语言,它把String也写成了一个类,我们先来看看String类中的成员变量:
在这里插入图片描述
可以看到String类中的成员变量是一个char类型的数组,还有一个int类型的hash。

        String str=new String("dhhiqhdi");
        String str1="adad";

事实上,不论我们是显示地new一个String对象还是隐式地使用双引号,都会在堆上创建对象的。那么String是引用类型,按照道理我们每一次都会new一个新的对象的话,是不是使用==比较两个String类都会得到false的结果呢?

        String str3="adad";
        String str1="adad";
        System.out.println(str1==str2);
        System.out.println(str1==str3);

在这里插入图片描述
这就奇怪了,为什么这跟我们的预期不一样呢?
在这里插入图片描述
我们把“ ”括起来的内容都会放到常量池中(“ ”括起来的内容也是一个字符串,也会有相应的value数组和hash值),每当我们创建了String对象,我们首先都会到常量池里面找找看,看看之前有没有存储过,如果我们是直接用“ ”进行赋值的,那么不管是多少个字符串引用,最终都会指向常量池中的字符串,但是如果此时我们进行了new String操作,我们会发现,此时堆上悄咪咪地出现了一个String对象,而此时我们在栈上创建的字符串引用就会指向它。那么有兄弟肯定要问了,那我们字符串的具体内容是怎么样实现的呢?之前不是说了吗,常量池中的也都是一个个鲜活的String对象。我们str指向的对象中的value数组也是会指向常量池中的value数组的,这样子就保持了字符串内容的一致性,毕竟都是指向同一个引用啊。

        String str3="adad";
        String str1=new String("adad");
        System.out.println(str1==str2);
        System.out.println(str1==str3);

在这里插入图片描述
所以我们现在new一个对象来看看,结果立马变了!

String中的一些方法

之前在C语言中,自己敲了一个又一个方法,着实是有点为难人了,现在我们只要了解个大概就可以上手使用了!

equals

当我们想要比较字符串中的内容的时候,就不要再使用==比较了,我们的String重写了Object中的equals方法,此时比较的就会是两个字符串的内容

char charAt(int index)

获取字符串对应位置的字符

int indexOf(int ch)

返回第一次出现ch的位置,没有返回-1。本质上我们的字符也就是一个个ASCII码值,所以直接‘a’,也是可以的。

int lastIndexOf(int ch)

从后往前找,还是返回位置。这里的indexOf方法中有很多重载,【 )区间的啊,返回出现的字符串的第一个字符的位置啊……

转化

String类中有valueOf方法,这个方法有很多重载

String str=String.valueOf(123);
String str=String.valueOf(1.55);
String str=String.valueOf(new int[]{1,2,3});

这个转化是双向的,我们不单单只有String这一个类啊。


int x=Integer.parseInt("111111");
double y=Double.parseDouble("11.55");

大概就是这么一个使用规则。

replaceAll,replaceFirst

(String regex, String replacement)
第一个参数是要换下的内容,第二个参数是换上的内容。

split

要注意的是这个方法是按照字符串来拆分的,所以参数应该是“ ”类型的。

substring

从某个位置获取到某个位置的方法。

字符串不可变

我们之前一直在强调,我们最后的倔强就是修改字符串的指向,没有说的修改字符串内容的这一说的,包括我们在上面说的这么好些方法,实质上都是返回的是new的新的对象。
在这里插入图片描述
我们说的字符串不可变,是因为我们存储字符的value数组被封装起来了,而String类中有没有提供对外的接口,所以我们没有办法在String类外边修改String字符串,而我同时我们的数组又是被final修饰的,所以我们没有办法改变一个字符串对象数组的指向,注意了,我们不可修改的是字符串对象的指向而不是字符串引用的指向,String str,我们这里的str不是想指谁就指谁?

StringBuilder&& StringBuffer

由于使用String中的方法的时候我们每一次都要new一个新对象,这就或多或少会造成我们内存的压力,究其根本原因就是因为我们没有办法直接修改一个String对象,那有没有一种办法,可以让我们直接对字符串进行操作呢?有的,我们这里的StringBuilder和StringBufffer就可以直接实现对字符串的操作:
在这里插入图片描述
我们可以看到这两种类的方法中return的都是this,需要注意的是StringBuilder和StringBuffer和String类是独立的,我们不可以以为这两者可以直接转化:
在这里插入图片描述
之前我们是利用构造方法实现了String向StringBuffer的转化,反之则需要调用toString方法。
需要注意的是StringBuffer每次使用的时候,都会消耗一部分资源用于保证线程安全,这也就导致了他会比StringBuilder慢一丢丢,这三个类都会有一些自己独特的方法,在这里继续讲解方法就显得没有那么有必要,所以大家可以查阅帮助手册来进行学习!
希望我的这边博客对兄弟们能有所帮助!
还是那句话:百年大道,你我共勉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值