Java的String、StringBuilder 和 StringBuffer类详解及区别

java基础(jdk1.8)

**

String相关

**

字符串在Java基础中是比较重要的,这里我们对String及StringBuffer和StringBuilder进行研究

      字符串的操作我们在String、StringBuffer、StringBuilder这里同时对这三个类进行分析

String

源码内容:

    1、String是一个final的class

    2、String实现了Serializable, Comparable, CharSequence三个接口

    3、String储存字符串用的是一个final的char数组

    4、String的构造方法传参可为空、字符数组(char [])、字节数组(byte [])和String字符串常量

根据源码,我们可以得出String的特点

1.String类不可被继承、且String字符串是一个常量

2.String类实现了compareTo方法、charAt、toString方法…

除此之外,我们要知道的还有


 String str = new String("123abc");

 String str1 = "123abc";

这两个到底创建了几个对象,它们分别储存在哪,区别又是什么?

这个容易牵扯到Java内存,这里可以戳戳看,但下面阅读不是太影响

我们知道的是new会将引用引用到堆空间,那么接下来就好办了

str = new String(“123abc”)

    1.str引用必定指向堆空间的new String(“123abc”)

    2.同时会从常量池(方法区的一部分)内寻找有无"123abc"这个字符串。方便理解起见,之后将常量池叫做String池

    3.String池没有这个字符串则创建一个对象在池中,有则不创建

这里注意

因为字符串经常创建,使用。所以String池为了节省空间、提高效率,String池不可重复

str1 = “123abc”

    1.str1没有使用new,那么str1自然直接引用到String池内

    2.String池内同样找是否已经有了同样的字符串

这里我们基本对这两有何区别已经了解,我们看一段代码和一个关系图来在加深印象


public class StrTest {

    public void strTest(){

        String s1 = "hello";
        String s2 = "hello";
        System.out.println(s1 == s2);

        String s3 = new String("hello");
        String s4 = new String("hello");
        System.out.println(s3 == s4);
        System.out.println(s1 == s3);

        System.out.println(s1 == s3.intern());

    }

    public static void main(String[] args) {

        StrTest strtest = new StrTest();

        strtest.strTest();

    }

}

结果


    true
    false
    false
    true

结果是此的原因也就出来了

上述我使用了s3.intern(),用它和s1比较,结果为true,这是intern将s3的引用从堆改到了String池。所以结果为true。

另外

==和equals

我们使用==比较的是地址,有一个方法为equals

equals方法源码


    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

这里,我们知道所有类都继承了Object类。

    看类是否将Object类的equals是否重写,重写则比较值、无则比较地址。

    而String将equals重写,所以equals方法是比较对象数值

    这时我们将之前的==改为equals,那么结果将全部为true

String类的其他方法

先瞧:

这里我挑几个看看

length()

    length()方法是字符串的长度。

String使用char数组,而length()源码调用的就是char数组的length方法

charAt(int index)

    charAt()方法是传入下标,返回下标对应的字符。

isEmpty()

    isEmpty()方法判断字符串是否为空

substring()

    substring()方法是截取字符串

根据传参的下标,对截取你所需要的部分(左闭右开)

在这里插入图片描述

StringBuilder 和 StringBuffer

StringBuilder和StringBuffer都继承的是AbstractStringBuilder,实现Serializable, CharSequence

而且两者的构造方法及方法基本一致,区别则是StringBuffer类的方法加了一个synchronized关键字,这个关键字保证了线程安全性。

因此StringBuilder是线程非安全类、StringBuffer是线程安全类

与String的区别:

1、String的值不可改变,而StringBuilder 和 StringBuffer的值可改变。

2、StringBuffer及Builder只能使用new关键字进行初始化,初始化调用其append方法再到super.append,如果非空则调用到System.arraycopy方法

3、StringBuffer及Builder没有重写equals方法1

StringBuilder 和 StringBuffer的常用方法:增删改

insert(int,obj)

从int位置插入obj(string、byte、char…)

delete(int,int)

从int到int删除(左闭右开)

replace(int,int,String)

左闭右开替换

length()

charAt(int index)

isEmpty()

substring()

补充

String a = "123";
//a在栈里,引用指向方法区里“123”这个对象(创建一个对象)
String b = "123";
//b指向方法区里“123”(未创建对象)
String c = new String("123");
//c 在堆创建一个对象并指向它,方法区有则不创建(创建一个对象)
String d = new String("456");
//d 在堆里和方法区分别创建一个(共创建两个对象)
String b = a+"12";
//这里并不是说b的值改变,而是将原来的b销毁,创建一个方法区的“12”对象,而这个a已经创建过了,最后将a+"12"共同创建一个新的对象(new堆上),和原来的b并不是同一个

注意

subString方法


    public String substring(int start, int end) {
        if (start < 0)
            throw new StringIndexOutOfBoundsException(start);
        if (end > count)
            throw new StringIndexOutOfBoundsException(end);
        if (start > end)
            throw new StringIndexOutOfBoundsException(end - start);
        return new String(value, start, end - start);
    }

返回的是一个new的对象

上一篇 》常用类

下一篇 》 异常处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值