1.先说字面量相加问题
java 预编译的问题
先来看一个实例 输出结果 false 和 true
原因和相关问题 因为string底层是用final修饰的 所以不可变
如果用字面量想加的话 编译期间 会预编译成要生成的字面量 ab
也就是相当于 stsum3="ab"
如果不是字面量相加 或者一个字面量和一个非字面量相加 java编译器不会预编译优化会产生一个新的对象 所以地址值不同
public static void main(String[] args) {
// 1.java 字面量预编译相关问题
// String st1 = "a";
// String st2 = "b";
// String st3 = "ab";
//
// String stsum1 = st1 + st2;
// String stsum2 = "a" + "b";
//
// System.out.println(st3 == stsum1);
// System.out.println(st3 == stsum2);
2.string api–获取功能
String string = "abcdef";
// 这块区分开一方法length()一个属性length
int length = string.length();
System.out.println("这是方法!" + length);
// 1.获取指定位置的字符串
System.out.println(string.charAt(0));// 输出a
// 2.获取指定字符串的位置
System.out.println(string.indexOf("a"));// 输出0
// 3..获取指定字符串的位置--重载方法根据ASCII码查找
System.out.println(string.indexOf(97));// 返回a所在的位置0
// 4.从指定位置开始截取字符串,特性:左包右不包
System.out.println(string.substring(0, 2));// 输出0 1两个位置的字符 那就是 a b
// 5.大小写互换函数
System.out.println(string.toUpperCase());
System.out.println(string.toUpperCase().toLowerCase());// 再变为小写
// 6.去除两端空格
String string2 = " abc ";
System.out.println(string2.trim());
// 7.按照指定字符 符号切割 将切割的字符变成 ,
String string3 = "ababcacd";
System.out.println(Arrays.toString(string3.split("a")));
}
}
3.聊聊stringbuffer和stringbuilder(1)
上文说国 string是一个fianl类,所以每次只要对string的实例对象追加一些字符(append方法)或者 非字面量+操作,内存里面就会生成一个新的string,这样开销很大,所以我们有了stringbuilder。。。
- 1.可变string类方法
- 2.string 底层 final
- 3.深入问题:*
stringbuilder 扩容机制
- 4.反转功能
public class String3 {
public static void main(String[] args) {
// 问题引入 因为stirng底层是final修饰的
// 所以 st从创建起不能被改变 只能再常量池中再重新生成一个新的字面量
// 如果频繁操作字符串 我们就会在常量池中创建很多无用的字面量
// 如果如此频繁操作 就会造成内存开销很大甚至泄露
// String st1 = "a";
// String st2 = "b";
// st1 = "a" + "b";
// // 1.可变字符串 stringbuilder
// // 无参构造方法 默认容量 16个字符
// StringBuilder sb = new StringBuilder();
// System.out.println(sb.capacity());
// // 2.有参方法 指定容量
// StringBuilder sb2 = new StringBuilder(19);
// System.out.println(sb2.capacity());
// // 3.指定字符串的构造器 容量等于 初始容量加+字符串的长度 例如: 16+3
// StringBuilder sb3 = new StringBuilder("123");
// System.out.println(sb3.capacity());
// // 这里要区分开 length和 capatity的区别
// // length是实际装载字符串的长度 capacity是容量
// System.out.println(sb3.length());
// 扩容机制 --当我们的length大于容量的时候 buileder会自动扩容
// StringBuilder sb4 = new StringBuilder("我爱你java");
// sb4 = sb4.append("java");
// sb4 = sb4.append("java");
// sb4 = sb4.append("java");
// sb4 = sb4.append("java");
//上面是长度18-大于容量-开始扩容
//当用有参构造的时候 不够用的第一步--吧容量变为16+有参字符长度
// System.out.println(sb4.capacity());
// //当用无参构造器的时候
// StringBuilder stringBuilder=new StringBuilder();
// //如果长度不够 会直接再原来容量基础上*2+2
16*2+2=34--第一次扩容
// stringBuilder.append("java");
// stringBuilder.append("java");
// stringBuilder.append("java");
// stringBuilder.append("java");
// stringBuilder.append("java");
// System.out.println(stringBuilder.capacity());
//反转功能
StringBuilder sBuilder=new StringBuilder("abc");
System.out.println(sBuilder.reverse());
4.聊聊stringbuffer和stringbuilder(2)
// 当我们解决了 string本身不可变问题的时候 我们要面对一个新的问题
// 同步问题
// 1.假设此字段在项目中不仅仅频繁访问
// 2.而且有多个线程都想对其进行操作 那么会出现某一时刻字符串内容不同步问题
// 3.此时我们采用stringBuffer 底层采用了synchronize关键字来实现保证线程安全
// 这两个类都是集成了AbstractStringBuilder,只是我们的追加append方法等一些方法
// 在stringbuffer中函数加上了synchronized
// 4.对于这两中容器的思考 1.假设说不是面向多个进程的数据 直接用builder就能达到项目要求
// 如果多进程同时访问的字段我们使用buffer保证安全 但是速度开始下降
5.关于equals问题
StringBuffer stringBuffer = new StringBuffer("zhan");
StringBuilder stringBuilder = new StringBuilder("zhan");
StringBuffer stringBuffer1 = new StringBuffer("zhan");
StringBuilder stringBuilder1 = new StringBuilder("zhan");
String string=new String("zhan");
String string1=new String("zhan");
System.out.println(string.equals(string1));
System.out.println(string.equals(stringBuilder));
//对比string本身 他们两都没有重写equlas
System.out.println(stringBuffer.equals(stringBuilder));
System.out.println(stringBuilder.equals(stringBuffer));
System.out.println(stringBuffer.equals(stringBuffer1));
System.out.println(stringBuilder.equals(stringBuilder1));