JavaSE三个特殊类---String类

String类

  • String类的两种实例化方式
    a.直接赋值
    (推荐使用此方式)
    String str = “Hello world”;
    b.通过构造方法实例化String类对象
    String str = new String(“Hello world”);

  • 字符串的比较
    public boolean equals(String str);

    在这里插入图片描述

Q请比较String中“==”与“equals( )”的区别。
A:“==”:本身是进行数值比较的,如果用于对象比较,那么所比较的就应该是两个对象所保存的内存地址数值的比较,而没有比较对象的内容。
“equals( )”:可以进行字符串内容的比较。

  • 字符串常量是String类的匿名对象
    在任何语言的底层,都不会提供有直接的字符串类型。现在所谓的字符串只是高级语言用户方便开发的支持而已。在java中,本身也没有直接提供字符串常量的概念,所有使用“”定义的内容本质上来讲都是String的匿名对象

那么之前出现的“String str = “Hello world””,本质上就是讲一个匿名的String类对象设置有名字,而且匿名对象一定保存在堆内存中。
tips:在进行制定内容比较时,将指定内容(字符串常量)写在前面,避免NullPointerException。
方式1:
在这里插入图片描述
以上面代码为例,如果用户没有输入时,一定会出现 NullPointException 问题。
方式2:任何字符串常量都是String类的匿名对象,所以该对象永远不会为null。
在这里插入图片描述

在此强烈建议方式2,把字符串写在前面。

  • String类的两种实例化的区别
    前面已经指出,String类有直接赋值和通过构造方法两种方式来实例化对象,那么使用哪一种更好以及彼此之间的区别有哪些呢?

a.直接赋值
在这里插入图片描述
前面已经说过,“==”比较的是两个对象所保存的内存地址的数值,但此处为什么会又会返回true呢。如下图:

在这里插入图片描述
为什么现在并没有开辟新的堆内存空间呢?
因为String类的设计使用了共享设计模式

在JVM底层实际上会自动维护一个对象池(字符串对象池),如果现在才有了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中。如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将其进行引用;如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用。

所谓的对象池就是一个对象数组(目的就是减少开销)

b.采用构造方法实例化对象
类对象使用构造方法实例化是标准做法。
在这里插入图片描述

在这里插入图片描述

可知,如果使用String构造方法就会开辟两块堆内存空间,并且其中一块堆内存将成为垃圾空间。除了这一缺点之外,也会对字符串共享产生问题。

范例:观察字符串共享问题
在这里插入图片描述

在String类中提供有方法入池操作:
public String intern( );

范例:观察入池操作
在这里插入图片描述
在这里插入图片描述
此时,因为实例化str1时使用了intern()使其保存进了对象池中,所以str2 实例化时直接在对象池中查找。

总结如下:
1.直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。
2.构造方法:会开辟两块堆内存空间,其中一块成为垃圾空间,不会自动保存在对象池中,可以使用intern()方法手工入池。

因此,一般我们会采用第一种方式即直接赋值。

- 字符串常量不可变更
所有的语言对于字符串的底层实现,都是字符数组,数组的最大缺陷就是长度固定。在定义字符串常量时,它的内容不可改变。

在这里插入图片描述
以上字符串的变更时字符串对象的变更而非字符串常量

在这里插入图片描述
可以发现字符串上没有发生任何变化,但是字符串对象的引用一直在改变,而且会形成大量的垃圾空间。正是因为String的特点,如果有很多用户都使用了同样的操作,那么产生的垃圾数量就相当可观了。

原则:
1.字符串使用就采用直接赋值。
2.字符串比较就使用equals()实现。
3.字符串别改变太多。

- 字符与字符串
字符串就是一个字符数组,所以在String类里面支持有字符数组转换为字符串以及字符串变为字符的操作方法。
在这里插入图片描述
其中,字符串和字符数组的互相转换是重点。
在这里插入图片描述
范例:判断一个字符串是否由数字组成。
在这里插入图片描述

- 字节与字符串
字节常用于数据传输以及编码转换的处理之中,在String中提供有队字节的支持。
在这里插入图片描述
应该注意的是,字节并不适合处理中文。按照程序的概念来讲,一个字符等于两个字节。字节只适合处理二进制数据。

- 字符串比较
之前使用过String类提供的equals()方法,该方法本身是可以进行区分大小写的相等判断。除了这个方法之外,String类还提供有如下的比较操作:
在这里插入图片描述

在String类中compareTo()方法是一个非常重要的方法,该方法返回一个整形,该数据会根据大小关系返回三类内容:

     1.相等:返回0
     2.小于:返回内容小于0
     3.大于:返回内容大于0

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

- 字符串查找
从一个完整的字符串之中可以判断指定内容是否存在,对于查找方法有如下定义:
在这里插入图片描述
其中,字符串的查找,最好用最方便的就是contains( )。而很多时候一些参数利用标记做一些处理,这时就利用startsWith()与endsWith( )来判断

  • 字符串替换
    使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:
    在这里插入图片描述
    - 字符串拆分
    可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。可用方法如下:
    在这里插入图片描述
    范例:实现字符串的拆分处理
    在这里插入图片描述
    范例:拆分IP地址
    在这里插入图片描述
    应该注意的是,有些内容无法拆分开就需要使用“\”转义。

范例:多次拆分
在这里插入图片描述

- 字符串截取
从一个完整的字符串之中截取处部分内容。可用方法如下:
在这里插入图片描述
在这里插入图片描述
注意:索引下标从0开始。

- 字符串的其他操作方法
在这里插入图片描述
范例:首字母大写
在这里插入图片描述

两只SB(StringBuffer 和 StringBuilder)

为了方便字符串的修改,提供StringBuffer类。在String中使用“+”来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法:
public synchronized StringBuffer append(各种数据类型 b);

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用StringBuffer。

注意:String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:
1.String变为StringBuffer:利用StringBuffer的构造方法或append()方法。
2.StringBuffer变为String:调用toString()方法;

除了append()方法外,StringBuffer也有一些String类没有的方法:
1.字符串反转
public synchronized StringBuffer reverse( );

在这里插入图片描述
2.删除指定范围的数据
public synchronized StringBuffer delete(int start , int end);

在这里插入图片描述
3.插入数据
public synchronized StringBuffer insert(int offset, 各种数据类型 b);

在这里插入图片描述

Q:请解释String , StringBuffer,StringBuilder的区别:
A: 1.String的内容不可修改,StringBuffer与StringBuilder的内容可以修改。
2.StringBuffer采用同步处理,属于线程安全操作;而StringBuilder采用异步处理,属于线程不安全操作。

猜你喜欢

转载自blog.csdn.net/Sun_GLL/article/details/83688193