(四)Java容器部分知识

目录

1.StringBuilder

2.字符串常量池(串池)

3.字符串拼接的底层原理

1.StringBuilder

相比于字符串进行拼接等操作,更方便快捷

StringBuilder sb = new StringBuilder();
//可以空参&有参构造
//常用方法
sb.append();
sb.reverse();
String str = sb.toString(); 

sb.length(); //查看长度
sb.capacity(); //查看容量

StringBuilder存储原理分析:

  • 默认创建一个长度为16的字节数组
  • 添加的内容长度小于16,直接存入数组中
  • 添加的内容大于16会扩容(原来的容量*2+2=34)
  • 如果扩容之后还不够,以实际长度为准,长度为多少就扩容为多少

2.字符串常量池(串池)

字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最常用的数据类型之一,大量频繁的创建字符串对象,极大程度地影响程序的性能,所以JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化:

  • 为字符串在堆区开辟一个字符串常量池,类似于缓存区
  • 创建字符串常量时,首先查找字符串常量池是否存在该字符串
  • 存在该字符串,返回引用实例(串池地址),不存在,实例化该字符串并放入池中

实现该优化的基础是因为字符串是不可变的,可以不用担心数据冲突,而且运行时实例创建的全局字符串常量池中有一个表,总是为池中每个唯一的字符串对象维护一个引用,这就意味着它们一直引用着字符串常量池中的对象,所以,在常量池中的这些字符串不会被垃圾收集器回收。

3.字符串拼接的底层原理

首先要分为两种情况,拼接等号右边没有变量/有变量,如下代码,

String s = "a" + "b" + "c";
//没有变量
String s1 = "a" + "b";
Sreing s2 = s1 + "c";
//有变量

如果拼接的时候有变量就会复杂一些,JVM会自动生成一个StringBuilder在堆内存中,然后执行相关操作:执行new String(“字符串1”) + new String(“字符串2”),会创建StringBuilder对象,并将字符串1和字符串2的内容追加其中,然后调用StringBuilder对象的toString()方法,将其转换为一个新的字符串对象,内容为”字符串1字符串2“,这个新的字符串存储在堆上。

也就是说,当编译器遇到 + 号这个操作符的时候,会将 new String(“s1”) + new String(“s2”) 这行代码编译为以下代码:

new StringBuilder().append("字符串1").append("字符串2).toString();

所以说,字符串拼接时如果直接用“+”的话,非常浪费时间和空间,底层原理仍然是StringBuilder,那不如直接用StringBuilder一步到位。

String是字符串类,属于引用数据类型。

总结:

  1. 字符串存储的内存原理:直接赋值会复用字符串常量池中,new的新出来不会复用,而是开辟一个新的空间
  2. ==号比较的到底是什么?:基本数据类型比较数据值,引用数据类型比较地址值
  3. 字符串拼接的底层原理:如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串;
    如果有变量参与,每一行拼接的代码,都会在内存中创建新的字符串,浪费内存。
  4. 所以说如果要拼接字符串,最好用StringBuilder类,不会创建很多无用的空间,全程就只有一个StringBuilder。

4.ArrayList集合

//创建方式
ArrayList<String> list = new ArrayList<>();

集合和数组的区别:

长度存储类型
数组不可变基本/引用
集合可变引用数据类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值