String,StringBuffer,StringBuillder的底层结构
一:StringBuffer的底层
(1)线程安全的字符串操作类
(2)通过synchronized关键字声明同步方法,保证多线程环境下数据安全
public synchronized StringBuffer append(String str) {
super.append(str);
return this;
}
(3)底层存储数据的Char[]数组,初始化时,该数组的长度是16。如果构造函数有新传入字符转str,则16基础上加str.length.
public StringBuffer() {
super(16);
}
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
(4)添加字符串的过程
-->先检查内部char[]数组是否需要扩容
-->如需要扩容则进行扩容,然后将原来元数据copy到新数组中。
-->再将新添加的元数据加入到新char[]数组中
public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
//检查char[]数组是否需要扩容,扩容,并将原来的数据copy进去新扩容的数组中
ensureCapacityInternal(count + len);
//将新添加的数据添加到StringBuilder中的char[]数组中,实现字符串的添加
str.getChars(0, len, value, count);
count += len;
return this;
}
/**
*元数组char[]的扩容过程
*/
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}
/**
*扩容实现
*/
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
二:StringBuillder的底层
(1)线程非安全的字符串操作类
(2)字符串的添加没有加同步处理,涉及到数组扩容,容易产生脏数据,破坏数据正确性
(3)底层结构和StringBuffer实现基本一样,只是没有做同步处理。
--->StringBuffer和StringBuillder都继承抽象类AbstractStringBuilder,该抽象类实现了字符串操作的方法。
--->StringBuffer和StringBuillder的实现,运用了模板方法的设计模式,将核心数据操作放在父类方法里,子类实现自己的独有特色的功能,涉及核心操作,调用父类方法。
三:String的底层
String类没有提供用于修改字符串的方法。String类对象为不可变字符串,如字符串string=”HELLO”永远只包含HELLO这几个字母,而不能修改其中任何一个字符。当然可以修改字符串变量string的引用,让它引用另一个字符串。
不可变字符串有一个优点:编译器可以让字符串实现共享。实际上只有字符串常量(使用“ ”声明,存储在字符串常量池中)是共享的,subStrng,+等操作产生的结果不能共享。
比较字符串值是否相等时使用equals()方法,不能使用, 比较的是字符串的地址是否相同。如果字符串在常量池中,可以使用==比较,因为指向的都是同一个字符串。
直接使用 ” ” 声明的String对象会直接存储在常量池中,(可以实现共享)
String str1=”first”;
jvm在运行时先查找常量池中是否有该字符串,如果有则直接返回该字符串的引用给first(实现了字符串 的共享);否则先在常量池中创建该字符串并返回引用。
此时只会在常量池中创建String对象,不会在堆中创建。String str2=new String(“second”);
该代码生成了两个String对象。因为使用了“”会现在常量池中查找是否存在second对象,没有则创建
否则不创建;在常量池创建完成后,由于使用了new,jvm会在堆中创建内容相同的String对象,并将引用
返回给str2.String str3=”what”; String str4=str3+”a nice day”;
运行时,+ 相当于new,所以堆中会有“what a nice day”对象;常量池中会有”what” “a nice day”两个对象,而不会有”what a nice day”对象。三者在执行速度方面的比较:StringBuilder > StringBuffer > String
String,StringBuffer,StringBuillder的底层结构的更多相关文章
- 【1】String,StringBuffer,StringBuillder的底层结构研究
一:StringBuffer的底层 (1)线程安全的字符串操作类 (2)通过synchronized关键字声明同步方法,保证多线程环境下数据安全 @Override public synchroniz ...
- final,finally,finalize有什么区别?String, StringBuffer, StringBuilder有什么区别?Exception和Error有什么区别?
继上篇JVM学习之后,后面将分三期深入介绍剩余JAVA基础面试题,每期3题. 题目一.final,finally,finalize有什么区别? /*请尊重作者劳动成果,转载请标明原文链接:*/ /* ...
- 关于String StringBuffer StringBuilder
0. String对象的创建 1.关于类对象的创建,很普通的一种方式就是利用构造器,String类也不例外:String s=new String("Hello world&qu ...
- String StringBuffer StringBuilder (转)
转自:http://www.iteye.com/topic/522167 众所周知,String是由字符组成的串,在程序中使用频率很高.Java中的String是一个类,而并非基本数据类型. 不过她却 ...
- 浅谈 Java 字符串(String, StringBuffer, StringBuilder)
我们先要记住三者的特征: String 字符串常量 StringBuffer 字符串变量(线程安全) StringBuilder 字符串变量(非线程安全) 一.定义 查看 API 会发现,String ...
- 转:String StringBuffer StringBuilder区别
转自:http://www.iteye.com/topic/522167 作者:每次上网冲杯Java时,都能看到关于String无休无止的争论.还是觉得有必要让这个讨厌又很可爱的String美眉,赤裸 ...
- 重温java中的String,StringBuffer,StringBuilder类
不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...
- LWIP的底层结构(物理层)
LWIP的底层结构(物理层) 转自:http://bluefish.blog.51cto.com/214870/158418 我们前面讲到说是ip层的发送和接收都是直接调用了底层,也就是设备驱动层的函 ...
- String | StringBuffer | StringBuilder 比较
2016的第一天,我决定写一篇博客来纪念这一天,希望一年好运吧. String|StringBuffer|StringBuilder这三者在我们学习JAVASE核心API的时候常常出来,而且大多数入门 ...
随机推荐
- 搭建vue项目的步骤
新建vue脚手架 vue-element-cms步骤: 1. vue create ……………(文件名)---这里取为vue-element-cms 2. 命令行工具进入这个文件夹,安装路由依赖包 n ...
- 使用Spring Validation优雅地校验参数
写得好的没我写得全,写得全的没我写得好 引言 不知道大家平时的业务开发过程中 controller 层的参数校验都是怎么写的?是否也存在下面这样的直接判断? public String add(Use ...
- Python read和write方法
Python read和write方法: read(): 从文件中读取字符串 注:Python 字符串可以是二进制数据,而不仅仅是文字. 语法: 文件对象.read([count]) count:打开 ...
- Django学习路17_聚合函数(Avg平均值,Count数量,Max最大,Min最小,Sum求和)基本使用
使用方法: 类名.objects.aggregate(聚合函数名('表的列名')) 聚合函数名: Avg 平均值 Count数量 Max 最大 Min 最小 Sum 求和 示例: Student.ob ...
- 一图看懂华为云DevCloud如何应对敏捷开发的测试挑战
作为敏捷开发中测试团队的一员,在微服务测试过程中,你是不是也遇到同样困惑:服务不具备独立验证能力.自动化用例开发效率很低等? 华为云DevCloud API全场景测试技术来支招~围绕API的全场景,打 ...
- Python File read() 方法
概述 read() 方法用于从文件读取指定的字节数,如果未给定或为负则读取所有.高佣联盟 www.cgewang.com 语法 read() 方法语法如下: fileObject.read(); 参数 ...
- PHP is_writable() 函数
定义和用法 is_writable() 函数检查指定的文件是否可写. 如果文件可写,该函数返回 TRUE. 语法 is_writable(file) 参数 描述 file 必需.规定要检查的文件. 提 ...
- Node.js 和 Python之间如何进行选择?
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://dzone.com/articles/nodejs-vs-python-which ...
- Azure DevOps+Docker+Asp.NET Core 实现CI/CD(一 .简介与创建自己的代理池)
前言 本文主要是讲解如何使用Azure DevOps+Docker 来实现持续集成Asp.NET Core项目(当然 也可以是任意项目). 打算用三个篇幅来记录完整的全过程 觉得有帮助的朋友~可以左上 ...
- 1、Java 开发环境配置
Java 开发环境配置 在本章节中我们将为大家介绍如何搭建Java开发环境. Windows 上安装开发环境 Linux 上安装开发环境 安装 Eclipse 运行 Java window系统安装ja ...