目录
一、String类
4.1 基本原理
Java中使用的字符串值都是此类对象。
创建方式:
直接赋值
new 一个字符串对象
public static void main(String[] args) { //直接赋值 String name = "zhangsan"; //new一个 String name1 = new String("LISI"); }
原理
String是一个final类,不能被继承
存储字符串的方式是字符数组
该数组是final的,表示不能改变数组地址
String值不可变
String也是使用常量池的,如果直接赋值,是在常量池中创建对象,如果使用new,是在堆中创建对象。
//部分源码 public final class String implements java.io.Serializable, Comparable<String>, CharSequence, Constable, ConstantDesc {}
4.2 常见字符串的方法
注意:因为字符串不可变,所以当我们操作字符串后需要用新的对象去接收改变后的结果,否则没用。
常见方法:
indexOf(),返回指定字符串第一次出现的位置。
lastIndexOf(),返回指定字符串最后一次出现的位置。
substring(),提取字符串中两个指定索引号之间的字符(两个索引不能为负值)
charAt(),返回指定索引的字符
concat(),连接两个或多个字符串,返回连接后的新字符串。
split(),把字符串分割为子字符串数组
replace(),替换指定子串或者与正则表达式匹配的子串。
toUpperCase(),把字符串转换成大写的。
toLowerCase(),把字符串转换成小写的。
public class Demo1 { public static void main(String[] args) { //直接赋值 String name = "Hello World! Hello World"; System.out.println(name.indexOf("World"));//6 System.out.println(name.lastIndexOf("World"));//19 System.out.println(name.substring(6, 10));//Worl System.out.println(name.charAt(15));//l System.out.println(name.concat("abc"));//Hello World! Hello Worldabc System.out.println(name.split("!")[0] + "," + name.split("!")[1]);//Hello World, Hello World System.out.println(name.replace("World","China"));//Hello China! Hello China System.out.println(name.toLowerCase());//hello world! hello world System.out.println(name.toUpperCase());//HELLO WORLD! HELLO WORLD } }
编译器优化机制
在使用+拼接字符串时,可能会发生编译器优化,例如:
public static void main(String[] args) { String name = "张三"; String name1 = "吃饭"; String name2 = "张三吃饭"; String name3 = name + name1; System.out.println(name3 == name2);//false //因为+左右有变量,变量是可变因素,所以为false String name4 = name + "吃饭"; System.out.println(name4 == name2);//false //因为+左右为字符串,所以产生了编译器优化,因为字符串不可变 String name5 = "张三" + "吃饭"; System.out.println(name5 == name2);//true }
我们可以用idea查看字节码文件可知这里是优化。
二、可变字符串
当需要频繁改变字符串时,应该使用可变的字符串。
StringBuilder:jdk1.5提供,性能高,安全低。(默认长度为16)
//部分源码 public StringBuilder() { super(16); }
StringBuffer:jdk1.0提供,安全性高,性能低
使用方法:
StringBuilder sb1 = new StringBuilder(); StringBuffer sb2 = new StringBuffer();
5.1 基本用法
append 追加
replace 修改
insert 插入
delete 删除
public static void main(String[] args) { StringBuilder sb1 = new StringBuilder("123"); StringBuffer sb2 = new StringBuffer(); sb1.append("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); System.out.println(sb1);//123aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa }
5.2 原理
使用无参构造时,默认创建数组大小为16个char;
可在创建时指定大小
如果hiding字符串,会设置大小为字符串长度+16.
public StringBuilder(String str) { super(str.length() + 16); append(str); }
当空间不够时,需要扩容,扩容大小是原本大小的二倍+2
//部分源码 int oldCapacity = value.length >> coder; int newCapacity = (oldCapacity << 1) + 2;
三、BigDecinal类
注意:使用BIgDecimal计算时,应用字符串作为保存数字的参数
作用:
-
小数的精确计算
-
超出long范围的整数计算
import java.math.BigDecimal; import java.math.RoundingMode; public static void main(String[] args) { BigDecimal bd = new BigDecimal("20"); BigDecimal bd1 = new BigDecimal("3"); BigDecimal bd2 = new BigDecimal("3456666666666666666666666666"); BigDecimal bd3 = new BigDecimal("35555555555555555555555555555"); //加法运算 23 System.out.println(bd.add(bd1)); //减法运算 17 System.out.println(bd.subtract(bd1)); //乘法运算 122903703703703703703703703678079629629629629629629629630 //可以计算超出long范围的值 System.out.println(bd2.multiply(bd3)); //除法运算 当除不尽时,我们还需要指定保留多少位小数,和保留小数的方式,例如:四舍五入(HALF_UP)等等 System.out.println(bd.divide(bd1,2,RoundingMode.HALF_UP)); }
例题
理解一下代码流程以及想出结果
public static void main(String[] args) {
String s1 = "abc";
String s2 = "123";
show(s1, s2);
System.out.println(s1 + "-----" + s2);
}
public static void show(String s1, String s2) {
s1 = "W" + s2;
s2 = "Q" + s1;
}
结果为
abc---------123