JAVA-StringBuilder和StringBuffer

news2024/11/20 7:18:31

一、认识String类

1.认识

String在Java中是字符串类型,但与其他类型不同。它是一个类,可以创建对象的类。与int、char等自待类型有些许不同。但它仍然是java提供的一种类型。

 类中有4个属性,这里主要认识一下value属性。它是实际存放字符串的引用。那么我们来看一下源码:

2.String的不可变性

可以看到value数组被final修饰,那么他里面的值是不可以变的。但是java又提供了非常多对String类操作的方法,对里面的value数组进行更改。但是实际上,他都是创建一个新的String类对其进行操作,并返回新的String类。

这样会有一个非常大的问题,有这样一个代码:

public static void main(String[] args) {
        String array = "a";

        for (int i = 0; i < 1000; i++) {
            //他在这里会不停的发生创建新的对象
            //并进行拼接
            //然后再返回新的对象
            array += i;
        }

        System.out.println(array);
    }

这会大大提升时间空间复杂度

那么以后在使用字符串并且,对字符串进行大量操作,或者不想创建新的String类的时候可以使用StringBuilder和StringBuffer

二、StringBuilder和StringBuffer

1.StringBuilder和Strinig的区别

这里使用StringBuilder进行对比

正常使用StirngBuilder进行拼接:

public static void main(String[] args) {
        StringBuilder s = new StringBuilder("a");
        for (int i = 0; i < 1000; i++) {
            s.append(i);//想当与String的+=
        }
        System.out.println(s.toString());
}

用StringBuilder模拟Stirng进行拼接:

    public static void main(String[] args) {
        StringBuilder s1 = new StringBuilder("a");
        for (int i = 0; i < 1000; i++) {
            StringBuilder tmp = new StringBuilder("");
            tmp = s1.append(i);
        }
        System.out.println(s1.toString());
        
    }

创建类本来就是一个复杂的过程,如果使用String他会创建1000次,那速度肯定是大大降低。

StringBuffer也是跟StringBuilder相同的操作,那StringBuilder和StringBuffer有哪些区别呢?这也是面试常考题

2.String、StringBuffer、StringBuilder的区别

  1. String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
  2. StringBuffer与StringBuilder大部分功能是相似的
  3. StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

这个第3项给大家解释一下:想要真正了解这个东西需要多线程的理解,这里给大家简单解释一下。

一边看图一边看我解释:

厕所可以看作是一种资源吧

StringBuffer更像家里的厕所,是有锁的。你在上厕所(你在使用资源)别人是进不来的。

StirngBuilder更像是公共场所,没有锁想进来就进来,那肯定没有家里的厕所有安全感。

所以:StringBuffer是安全的,StringBuilder是不安全的。但目前我们写的程序都是单线程的

3.String、StringBuffer、StringBuilder的运行时间区别

使用System.currentTimeMillis()方法可以获取当前时间的一个毫秒数。

用 当前时间-指向前时间 = 时间差

public static void main(String[] args) {
        long start = System.currentTimeMillis();//获得当前时间毫秒数
        String s = "";
        for(int i = 0; i < 100000; ++i){
            s += i;
        }
        long end = System.currentTimeMillis();
        System.out.println("String" + (end - start));

        start = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer("");
        for(int i = 0; i < 100000; ++i){
            sbf.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuffer" + (end - start));

        start = System.currentTimeMillis();
        StringBuilder sbd = new StringBuilder();
        for(int i = 0; i < 100000; ++i){
            sbd.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuilder" + (end - start));

}

 结果:

可以看到String与StirngBuilder和StringBuffer的区别是巨大的。但这里并没有体现出StirngBuilder和StringBuffer之间的差距,可能是现在做了优化。不过在不涉及多线程的时候推荐使用StirngBuilder要更快一点。

三、StringBuilder和StringBuffer的常用方法

想要了解String常用方法的可以看我这篇博客:String类和String类常用方法-CSDN博客

1. StringBuff append(String str) 拼接字符串

StringBuff append(String str)在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、 double、float、int、long、Object、String、StringBuff的变量
public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("");
        int[] arr = new int[]{1,2,3,4,5};
        stringBuilder.append("a");
        stringBuilder.append(1);
        stringBuilder.append(1.5);
        stringBuilder.append('c');
        for (int a: arr) {
            stringBuilder.append(a);
        }
        System.out.println(stringBuilder.toString());//a11.5c12345
}

2.char charAt(int index) 获取index位置的字符

  public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("hello");
        System.out.println(stringBuilder.charAt(0));//h
        System.out.println(stringBuilder.charAt(-1));//异常
        System.out.println(stringBuilder.charAt(stringBuilder.length()));//异常
  }

3.int length() 获取字符串的长度

 public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("hello");
        System.out.println(stringBuilder.length());//5
 }

4.int capacity() 获取底层保存字符串空间总的大小

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("hello");
        System.out.println(stringBuilder.capacity());//21
}

 

5.void ensureCapacity(int mininmumCapacity) 扩容

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("hello");
        System.out.println(stringBuilder.capacity());//21
        stringBuilder.ensureCapacity(30);
        System.out.println(stringBuilder.capacity());//44 = 21 * 2 + 2
}

6.void setCharAt(int index, char ch) 将index位置的字符设置为ch

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("hello");
        stringBuilder.setCharAt(2,'a');//注意要输入char类型
        System.out.println(stringBuilder);//healo
}

 

indexOf函数找不到相应的字符串返回-1

7.int indexOf(String str) 返回str第一次出现的位置

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaabb");
        System.out.println(stringBuilder.indexOf("bb"));//2
}

8.int indexOf(String str, int fromIndex) 从fromIndex位置开始查找str第一次出现的位置

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaabb");
        System.out.println(stringBuilder.indexOf("bb",4));//8
}

9.int lastIndexOf(String str) 返回最后一次出现str的位置

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaabb");
        System.out.println(stringBuilder.lastIndexOf("aa"));//6
}

原理是从后往前找

10.int lastIndexOf(String str, int fromIndex) 从fromIndex位置开始找str最后一次出现的位置

原理是从指定位置从后向前找
public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaabbaa");
        System.out.println(stringBuilder.lastIndexOf("aa",5));//0
        System.out.println(stringBuilder.lastIndexOf("ac",5));//-1找不到
}

11.StringBuff insert(int offset, String str) 在offset位置插入:八种基类类型 & String类型 & Object类型数据

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaabbaa");
        //aaxxxbbccaabbaa
        //不会覆盖原有字符,原位置字符全部往后移
        System.out.println(stringBuilder.insert(2, "xxx"));

        //aaxxxbbccaabbaaxxx,证明可以当追加函数使用
        System.out.println(stringBuilder.insert(stringBuilder.length(), "xxx"));

        //报错
        //说明,要紧跟字符串末尾追加
        System.out.println(stringBuilder.insert(stringBuilder.length()+1, "xxx"));

    }

12.StringBuffer deleteCharAt(int index) 删除index位置字符

 public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaa");
        System.out.println(stringBuilder.deleteCharAt(2));//aabccaa

 }

13.StringBuffer delete(int start, int end) 删除[start, end)区间内的字符

注意:左开右闭[ ,)

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaa");
        System.out.println(stringBuilder.delete(2, 4));//aaccaa
}

 

14.StringBuffer replace(int start, int end, String str) 将[start, end)位置的字符替换为str

 注意:左开右闭[ ,)

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaa");
        System.out.println(stringBuilder.replace(2, 4,"xx"));//aaxxccaa
        System.out.println(stringBuilder.replace(2, 
                            stringBuilder.length() + 1,"xx"));//aaxx
}

最后一种虽然可以指向成功但绝对不建议这么写

15.String substring(int start) 从start开始一直到末尾的字符以String的方式返回 

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaa");
        System.out.println(stringBuilder.substring(2));//bbccaa
        System.out.println(stringBuilder.substring(stringBuilder.length()));//什么都不打印
        System.out.println(stringBuilder.substring(stringBuilder.length() + 1));//报错
}

16.String substring(int start,int end) 将[start, end)范围内的字符以String的方式返回

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaa");
        //这里不报错是因为左开,右闭
        System.out.println(stringBuilder.substring(2, stringBuilder.length()));//bbccaa
}

17. StringBuffer reverse() 反转字符串

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaa");
        //这里不报错是因为左开,右闭
        System.out.println(stringBuilder.reverse());//aaccbbaa
}

18.String toString() 将所有字符按照String的方式返回

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("aabbccaa");
        //StringBuilder 以 String 类型返回
        System.out.println(stringBuilder.toString());//aabbccaa
}

这里要着重讲一下,原本是StringBuilder类型,要转换为String类型,就可以用toString。

 注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:

  • String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
  • StringBuilder变为String: 调用toString()方法。

 

四、面试题

1.

String str = new String("ab"); // 会创建多少个对象
1.会创建一个对象

String str = new String("a") + new String("b"); // 会创建多少个对象
2.a创建一个对象 + b创建一个对象 + 将他们拼接起来需要一个对象 = 3个对象

一共创建了4个对象

 2.String、StringBuffer、StringBuilder的区别

  • String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
  • StringBuffer与StringBuilder大部分功能是相似的 StringBuffer采用同步处理,属于线程安全操作;
  • 而StringBuilder未采用同步处理,属于线程不安全操 作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2166074.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI 赋能大模型:从 ChatGPT 到国产大模型的角逐与发展契机

在当今科技飞速发展的时代&#xff0c;大模型作为人工智能领域的关键技术&#xff0c;正引发着深刻的变革。它们在自然语言处理、计算机视觉、语音识别等众多领域展现出了惊人的潜力&#xff0c;为各行各业带来了前所未有的机遇和挑战。本文将深入剖析大模型的技术原理、市场态…

字符串的join和os.path.join()

>>> key "".join("I love China.")>>> keyI love China.>>> key.join("--xwf")-I love China.-I love China.xI love China.wI love China.f为什么执行key.join("--xwf")的结果不是“I love China.--xwf”…

鄂尔多斯市鄂托克旗巴音乌苏六保煤矿5MW分布式光伏项目案例分析

摘 要&#xff1a;分布式光伏发电利用太阳能光伏板&#xff0c;分散布置在各区域&#xff0c;通过小规模、模块化并网或独立使用。其特点为就近发电、并网、转换和使用。技术进步和政策支持降低了光伏组件成本&#xff0c;推动了分布式光伏监控系统在多个领域的广泛应用。在全球…

【学习笔记】UWB技术定位原理

UWB技术还没有完全普及&#xff0c;却在慢慢兴起&#xff0c;一旦爆发&#xff0c;势不可挡也。 01-什么是UWB&#xff1f; UWB&#xff08;Ultra Wide Band&#xff09;是一种无载波通信技术&#xff0c;UWB不使用载波&#xff0c;而是使用短的能量脉冲序列&#xff0c;并通…

TikTok多语言商城系统源码+落地页 附搭建教程

TikTok多语言商城系统源码落地页 附搭建教程 环境 nginx php7.4.33 redis5.0.8 Memcached 1.6.6 mysql5.6 phpMyAdmin 伪静态 location / { try_files $uri $uri/ /index.php?$query_string; } 源码下载&#xff1a;https://download.csdn.net/download/m0_660477…

CVPR2021 安全AI挑战者计划第六期赛道一第二名方案分享 (UM-SIAT队)

关联比赛: CVPR2021 安全AI挑战者计划第六期&#xff1a;防御模型的白盒对抗攻击 CVPR2021 安全AI挑战者计划第六期赛道一第二名方案分享 &#xff08;UM-SIAT队&#xff09; 1.赛题简介 1.比赛通过15个防御模型测试攻击算法&#xff0c;其中包括13个在CIFAR-10上训练的模型…

单刀单掷(SPST)及单刀双掷(SPDT)模拟开关

单刀单掷(SPST)及单刀双掷(SPDT)模拟开关是对继电器元件的一种模拟简化, 本质上还是一种用开关控制的开关. 我们先从单刀双掷(SPDT)模拟开关与继电器的一个对比中了解其特性. 单刀双掷(SPDT)模拟开关 通过菜单 绘制--有源集成电路--添加模拟开关(SPDT) 可以添加一个单刀双掷…

我与Linux的爱恋:进程创建|终止

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;Linux的学习 ​ 文章目录 一、进程创建**fork函数**写时拷贝 二、进程终止进程退出的常见方法 一、进程创建 fork函数 在Linux中fork函数是非常重要的函数&#xff0c;它从已存在进程…

黑马智数Day4-2

渲染基础Table列表 封装获取企业列表接口 export function getEnterpriseListAPI(params) {return request({url: /park/enterprise,params}) } 组件中获取数据 <script> import { getEnterpriseListAPI } from /apis/enterprise export default {name: Building,dat…

C++ | Leetcode C++题解之第435题无重叠区间

题目&#xff1a; 题解&#xff1a; class Solution { public:int eraseOverlapIntervals(vector<vector<int>>& intervals) {if (intervals.empty()) {return 0;}sort(intervals.begin(), intervals.end(), [](const auto& u, const auto& v) {retur…

直播平台美颜功能开发方案:基于视频美颜SDK的集成详解

本篇文章&#xff0c;小编将于大家共同探究视频美颜SDK的美颜功能开发方案&#xff0c;帮助开发者深入理解其集成过程及关键技术。 一、美颜功能的重要性 在竞争激烈的直播市场中&#xff0c;直播平台如何提升用户体验至关重要。美颜功能不仅能够改善主播的形象&#xff0c;提…

桌面专业版【查看MAC和ip地址】

UOS统信查看MAC和ip地址的方法。 文章目录 查看方法一、图形化界面查看二、命令查看 查看方法 一、图形化界面查看 打开控制中心-网络-网络详情中-Mac地址就是您电脑的mac地址&#xff0c;IPV4就是您电脑的ip地址。 二、命令查看 桌面右键选择在终端中打开&#xff0c;输入i…

9.25度小满一面

1.map的底层 2.unorder_map哈希表有自己实现过吗&#xff1f;哈希冲突 3.poll和epoll和select的优缺点、 4.线程同步机制是用来做什么的? 5.五子棋项目问题-- 算法题: 6.LeetCode.重排链表 给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0…

Linux:地址分区——常量区、全局区、堆区、栈区

平台&#xff1a;Linux。本次实验是基于Linux平台&#xff0c;结论和其他平台大体相同&#xff0c;如有出入&#xff0c;也属于正常现象。实验内容&#xff1a;大致验证地址空间的各个分区。 结论如图&#xff1a; 结论说明&#xff0c;由低地址向高地址&#xff1a; 代码区&a…

Cortex-A7和Cortex-M7架构处理器取中断向量全流程分析

0 参考资料 Cortex M3权威指南(中文).pdf ARM Cortex-A(armV7)编程手册V4.0.pdf1 Cortex-A7和Cortex-M7处理器架构取中断向量全流程分析 1.1 什么是中断向量&#xff1f; 中断向量就是中断服务函数入口地址&#xff0c;例如我们发生了EXTI0中断&#xff0c;就需要执行EXT0中…

JavaScript 基础 - 第22天_Webpack模块打包工具

Day03_Webpack模块打包工具 目录 Webpack 简介与体验案例 - 打包注册用户网页插件 plugins 和加载器 loader 的使用案例 - 注册用户完成 - npm 作用在前端项目Webpack 开发服务器&#xff0c;打包模式调试代码 source map配置 路径 学习目标 了解 Webpack 的作用掌握 npm …

el-table中根据状态改单元格样式

需求&#xff1a;el-table中&#xff0c;有一列需要根据状态不同&#xff0c;显示的样式也不通。 解决方法&#xff1a; :cell-style"cellStyle" <el-table:data"tableData"style"width: 100%"size"mini"border:header-cell-style…

基于大数据可视化的化妆品推荐及数据分析系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Html--笔记01:使用软件vscode,简介Html5--基础骨架以及标题、段落、图片标签的使用

一.使用VSC--全称&#xff1a;Visual Studio Code vscode用来写html文件&#xff0c;打开文件夹与创建文件夹&#xff1a;①选择文件夹 ②拖拽文件 生成浏览器的html文件的快捷方式&#xff1a; &#xff01;enter 运行代码到网页的方法&#xff1a; 普通方法&#xff1a…

毕业设计选题:基于ssm+vue+uniapp的自助购药小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…