目录
- String
 - 字符串拼接
 - 字符串截取
 - 与数字相接
 - 不可变字符串
 - 检测字符串是否相等
 - 字符串常量池
 - 空串和null串
 - 码点与代码单元
 - String API
 - 字符串数组
 - 构建字符串
 - buffer机制
 - String、StringBuilder、StringBuffer 区别
 
- 比特流、网络流、文件流
 
String
字符串拼接
除了基本类型都叫引用类型。
public class Test{
	public static void main(String[] xxx){
		String x1 = "abcdef";
		String x2 = "12314";
		System.out.println(x1 + x2);
	}
}
 

 引用类型同样类型的大小就不一样了。
 任何引用类型都由基本类型组成。
字符串截取
public class Test{
	public static void main(String[] xxx){
		String x1 = "abcdef";
		String x2 = "012314";
		String x3 = x2.substring(2, 4);
		System.out.println(x3);
	}
}
 
substring(2,5); // [2, 4)
 
与数字相接
public class Test{
	public static void main(String[] xxx){
		String x1 = "abcdef";
		String x2 = "012314";
		String x3 = x2.substring(2, 4);
		System.out.println(x3);
		String x6 = "afd" + 33;
		int a = 90;
		float b= 234.34f;
		String x7 = x6 + a + b;
		System.out.println(x7);
	}
}
 

不可变字符串
由于长度会发生改变,不能在原地修改,所以引用指向别的地方。
 
检测字符串是否相等
经常用C++的可能会使用 ==
 而在java中 == 只能判断位置是否相等。
 在java中判断字符串相等使用equal。
equals 给字符串比较的时候是值,给其他引用类型比较时,仍然是地址。
字符串常量池
字符串创建时,先从常量池中寻找,要是有的话就不再创建了,而是指向它。
 但如果 是 new 出来的,则它是与众不同的,不进入常量池中,而是单独创建。
 
 
空串和null串
空串和null串并不相同:
 空串""是有空间的,而null是空引用不占空间。
码点与代码单元
public class Test{
	public static void main(String[] xxx){
		String x1 = "abcdefghijklmn";
		int w1 = x1.length(); // 获取字符串的长度
		char w2 = x1.charAt(3); // 获取第四个字符
		int w3 = x1.codePointAt(3);	// 获取第四个字符编码
		int w4 = w2; // 这种获取编码的方式比较好记
		System.out.println(w1);
		System.out.println(w2);
		System.out.println(w3);
		System.out.println(w4);
	}
}
 

String API
api:相当于一个帮助文档,可以查询现成的方法如何使用。
一些常用的:
 
 
 通过看api就能知道对应如何使用:
public class Test{
	public static void main(String[] xxx){
		String s1= "abcdefg";
		String s2 = "def";
		String s3 = s1.replace("cd","kk"); //替换
		int idx = s1.indexOf(s2); //子串起始位置
		System.out.println(idx);
		System.out.println(s3);			
	}
}
 

字符串数组
string.split(t) 根据t切割,返回字符串数组。
构建字符串
有些时候,需要由较短的字符串构建字符串,例如,按键或来自文件中的单词。采用字符串连接的方式达到此目的效率比较低。每次连接字符串,都会构建一个新的 String 对象 ,既耗时 , 又浪费空间。
使用 StringBuilder 类就可以避免这个问题的发生。
 在需要构建字符串时就凋用 toString 方法,将可以得到一个 String 对象,其中包含了构建器中的字符序列。
 StringBuilder();
 toString();
public class Test{
	public static void main(String[] xxx){
		String a = "adsf";
		a = a + "adfsdg";
		
		StringBuilder b = new StringBuilder();
		b.append("dfdf");
		b.append("sdvfsv");
		System.out.println(a);
		System.out.println(b.toString());				
	}
} 
 

 简单对比一下时间:
public class Test{
	public static void main(String[] xxx){
		long start = System.currentTimeMillis();
		String a ="";
		for (int i = 0; i < 10000; i++){
			a +="a";
		}
		long end = System.currentTimeMillis();
		
		long start1 = System.currentTimeMillis();
		StringBuilder b = new StringBuilder();
		for (int i = 0; i < 10000; i++){
			b.append("a");
		}
		long end1 = System.currentTimeMillis();
		System.out.println(end - start);
		System.out.println(end1 - start1);
	}
}
 

 明显快很多很多。
时间戳currentTimeMillis()
所有计算机都是从1970年01月01日08时00分00秒开始计算的。
buffer机制
分页:是把整个虚拟和物理内存空间切成一段段固定尺寸的大小。即划分逻辑地址空间至固定大小的页(Page),划分物理内存空间至固定大小的帧(Frame),并建立方案,转换逻辑地址为物理地址(pages to frames)。在 Linux 下,每一页的大小通常为 4KB。
StringBuilder 比 String 快的原因:
 多个单个变量存储在多个页中,数组中的多个元素可以存在一个页中,一个页是4KB。 // 这里写的不一定对。有知道的可以纠正一下。
 所以实际上的内存占用要比想象中多的多。
String字符串不可变,每次改变都要占用4kb大小去储存新的,这样内存会浪费很多,内存压力大,运行速度自然也会很慢。
 而StringBuilder内存可以指定。会提前申请8kb的足够空间,每次修改就可以有充足的空间在原地址修改,自然就快了。
底层就是开辟一个较大的数组。
 StringBuffer 底层就是char 数组。
 像这种提前申请空间节省内存的机制叫做 buffer 机制。
 
 
 常用来处理文件流,网络流。
流:本质就是基本类型数组。
String、StringBuilder、StringBuffer 区别
StringBuffer 里面加了锁,保障多线程下的安全,速度稍微慢一丢丢。也差不多,都是远远快于String。
比特流、网络流、文件流

 上面也说了流本质就是基本类型数组。
 如:byte二进制每8位存进数组一个数、
 short二进制每16位存入数组一个数。其他与之类似。
 一般都用byte数组是一个万能数组,因为其他类型都是他的倍数。
 例如8位还原成32位:
 
文件流:文件以二进制存储,通过上述方式解析成数组后,通过编码再次解析,显示在我们的屏幕上。 不同文件的头部会有不同固定的bit来记录是哪种编码。
网络流:与文件流相同的原理。



![[Volo.Abp升级笔记]使用旧版Api规则替换RESTful Api以兼容老程序](https://img-blog.csdnimg.cn/c857144b47a2486996a4b3476ca8b2d3.png)














