IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> String 、StringBuffer、StringBuilder 三者的异同(重点面试题) -> 正文阅读

[Java知识库]String 、StringBuffer、StringBuilder 三者的异同(重点面试题)

每日一语:你要逼自己优秀,因为只要变优秀了,所有事才会跟着好起来。?

前言:在学习Java的时候我们也会遇到一些面试经常出的面试题,为了以后的复习和总结,我决定把这些面试题一一给大家总结出来,希望能带给大家一些帮助,如果本文中有哪些总结不到位或者总结出错的地方,希望大家斧正!


String 、StringBuffer、StringBuilder 三者的异同。

一:

字符序列可不可变
String? ? 不可变
StringBuffer? ? 可变
StringBuilder? ? ?可变

二:

StringBuffer 和 StringBuilder 的一些区别
StringBuffer线程安全,效率低。底层为char [] , jdk1.0。
StringBuilder线程不安全,使用效率高 底层为 char[]? , jdk 5.0 新增。

三 :思考为什么String是不可变的 StringBufferStringBUilders是可变的?

我们可以通过查看 以上三者的源码来分析。

String

StringBuffer:

StringBuilders:

?我们可以通过上面的三个底层源码可以看到三者都是用char[ ]来存储,为什么就 String 是不可变的呢? 我相信细心的小伙伴已经发现了 ,就 String final ,则String是不可以变的。(如果有小伙伴对 final 不是很了解,我过几天会总结一下final的知识点。)?

上面虽然简述了为什么可变不可变的原理,但是面试题可没上面几句简单,所以下面就是正真的重点!!!仔细看!!!

我们先进行源码的分析:

String str = new String(); //char[0]
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};

我们能知道这个是String的创建方法。

StringBuffer stringBuffer = new StringBuffer();

接下来我们查看一下StringBuffer的底层源码:

再查看super:

在查看value:

从源码我们能知道 StringBuffer 在创建一个新空间时,是首先构造一个字符串生成器,其中不包含字符,初始容量为16个字符。?

StringBuffer stringBuffer = new StringBuffer();
//相当于底层创建了一个长度为16 char[] 数组
stringBuffer.append('a'); //value[0] = 'a';
stringBuffer.append('b'); //value[1] = 'b';
stringBuffer.append('c'); // value[2] = 'c';

当我们使用:

StringBuffer stringBuffer = new StringBuffer("abc");

我们查看底层源码:

?我们能知道他是会创建一个 str.length() + 16 的数组长度。

StringBuffer stringBuffer = new StringBuffer("abc");
//char [] value = new char ["abc".length() + 16]

通过上述对源码的查询我们能知道StringBuffer之所以可变是因为他有大量的数组空间,我们可以通过在数组上修改通过对字符串的修改!!!

这样我们就正真的知道了为啥?StringBuffer 是可以变的了(StringBuildersStringBuffer 的结构是相同的,上述结论也符合StringBuilders


拓展一:

我们接下来要对StringBuffer的可变进行一些问题的延申:

我们通过上述源码分析我们能知道因为StringBufferchar[] 数组的增大才可以使字符串变成可变性,一般情况StringBuffer初始话就比字符串长度多16个,如果我们一直对字符串进行添加处理直到超过初始化定义的长度会怎么办呢???

是会溢出还是会有一些解决办法呢???

我们可以在对源码进行分析:

?这段源码的作用就是对添加后的字符串长度是否超过底层数组的长度进行一个判断,如果超过原来的底层数组就会执行newCapacity这个函数。接下来我们再来查看这个函数的源码:

?通过对这个源码的分析我们能知道:这个是创建一个原来长度两倍加+2的长度的数组。

再来一起分析上面的几个代码我们可以知道如果原来的数组容量不够的情况下,我们会创建一个为原来长度两倍加2的一个新数组,再把原来的数组内容复制到现在这个数组中,并且在进行判断添加后的数组是否能大于添加后的长度,如果还是达不到则继续创建新的更大的数组,直到能大于目前添加后字符串的长度为止。


?

拓展二:

String、StringBuffer 和 StringBuilders三者的效率比较。

我们可以通过下面执行的代码来判断一下三者的执行效率:

package StringMoth;

public class demo3 {
    public static void main(String[] args) {
        long start_time = 0L;
        long end_time = 0L;
        String text = "";
        StringBuffer stringBuffer = new StringBuffer("");
        StringBuilder stringBuilder = new StringBuilder("");
        //开始对比
        start_time = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            stringBuffer.append(String.valueOf(i));
        }
        end_time = System.currentTimeMillis();
        System.out.println("Buffer的执行时间为:"+(end_time-start_time));

        start_time = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            stringBuilder.append(String.valueOf(i));
        }
        end_time = System.currentTimeMillis();
        System.out.println("Builder的执行时间为:"+(end_time-start_time));

        start_time = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            text = text + i;
        }
        end_time = System.currentTimeMillis();
        System.out.println("String的执行时间为:"+(end_time-start_time));
    }
}

输出结果:

我们能直到StringBuilders的效率是最高的,Buffer其次而String是效率最低的。

我们通过上面介绍的底层原理我们能知道String是不可变性的,如果添加一个新的字符串他则会开辟一个新的空间,然后把新的字符串放进这个新的地址中,因为每一次添加Sting都会开辟一个新的空间,所以会导致String的效率会很慢。

而Buffer和Builders则不同,它们都有多余的数组空间,在字符串长度不大于原数组长度时不会开辟新的空间,而是添加到空余的数组里面,这样就会使其效率高的很多!?

而Builders是没有锁的,它可以同时进行多个操作,而Buffer是有锁的,只能同时进行一个操作,导致效率没有Builders的效率高。(这个地方我不是很确定,如果有大佬觉得错了希望能指正一下,我下去我也在查查别的资料!!)

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-03 12:54:30  更:2021-12-03 12:54:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:08:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码