底层是char类型的数组 char[]
replace():替换
split():切分
indexOf():第一个字符所在位置,从0开始算
substring(3, 6):字符串截取,包括3不包括6
字符串不可变
本质上是数组,数组是固定值,想往后延伸的话可能后面有别的程序运行,越界检测。所以不能在原地址变,指向了新的地方
不重复创建
String s1 = "aaa";
String s2 = "aaa"; //如果存在这个值的话,那再定义个变量等于他这个值,那么这个变量不再创建也指向这个值。
boolean x = s1 == s2;
非基本类型String比较是否相同,比较的是指向是否相同
在java里面如果没有人记录他了,就会被当成垃圾自动回收
字符串常量池
- 字符串在常量池中没人指向他的话不会被回收
- 遇到new一定是开辟新的空间,不在常量池
用 equals() 比较字符串的值是否相同
equals()的作用:
- 每个类都有这个方法,都是集成Object,默认和==一样比较指向是否相同
- 字符串中对这个方法进行了重写,仅比较值
- 重写equals还需要重写hashcode(),因为hashmap的使用需要这两个方法配合
- 面试题还会问如何打配合,hashmap存放数据原理
空串与Null串
String s1 = null; //不占空间
String s2 = ""; //{'\0'},占空间
API:接口带说明文档
其中,打算法用的多的:
split()
- char类型本来的数可以直接用int类型的来表示,想看多少直接用int类型表示就行
输入字符串的时候不能用空格,因为空格也属于字符串
回车的话也会被吃,所以让他吃一次。前面没有那三行的话,就不用敲回车了,就不用吃回车了k4,直接输入就可以了
构建字符串
秒数从1970年开始记录
String、StringBuffer、StringBuilder 有什么区别
- 都是搞字符串拼接
- StringBuilder和StringBuffer速度远远高于String
- StringBuffer里面加了锁,速度稍微慢一点点
- StringBuilder多线程并发操作不安全和StringBuffer多线程并发操作下安全
内存构造
- 地址空间是指系统能够使用的总内存范围,取决于系统的位数(如64位)。
- 每个地址指向的大小是指通过该地址访问的实际数据大小,通常为1字节。
每个地址是指向1字节的内存,但地址本身的大小(即地址值的存储空间)取决于系统的位数。在32位系统中,地址通常是4字节,而在64位系统中,地址通常是8字节。
- 内存按页进行存储数据,如果按块进行存储,那么对内存的读写就会按块,每次读写的时间开销就会很大。对页进行存储,每次存储4kB(4096字节)。存储三个页,只需要下达三次地址指令即可。
- 一个内存页只有一个总地址,第一个数据在第一个位置很容易找到,但其他数据都定位不到,多个变量就找不到(不同变量大小不一致)所以一个内存页能放一个变量
如果只存int类型,会浪费很多空间。内存页越大,读取的速度越快(读的页数少),但是浪费的越多,容易内存不足;内存越小,读取的次数就多(读的页数多了),读取的速度就慢,浪费的空间也越低。所以折中取4KB。-----操作系统分配的最小单元是一个内存4KB
原地址不可变值---字符串
后面4096次他得带着前面那些内容,循环是每次一个一个加,所以每次申请空间都要带着前面的
本地址可变---StringBuilder和StringBuffer
能极大减少内存的损耗。
StringBuilder前身是StringBuffer
缓冲区--Buffer(会申请很大空间,速度很快,不分语言,底层数组,对内存损耗小)
缓冲区空间越大,缓存次数越多。增加数据后空间不够就会缓存,缓存至满了之后才申请空间,所以对空间的申请少,对空间消耗少
文件流-stream等(数组)操作,网络流操作---都需要缓冲区
- 数组里面的数据可以放在一个内存页,因为长度相同,可以确定具体的位置
- 弱类型语言不区分类型,由于默认不区分类型,所以它的数组里边存数据的时候可以各种类型都存到一块。每个数据大小不一样,把它往一个内存页放,他没办法定位到其他数据。不好定义,它对内存的消耗非常大,运行起来慢。
只要是文件操作都要指定编码,不指定都是ASCll