举例:包装类(Integer) -> String
🌳Integer面试题
- 示例一:两个对象,所以是false
- 示例二:if (i >= -128 && i <= 127)时不创建对象
- 示例三:大小超过了127,直接new Integer
自动装箱底层源码:
- 示例四:只要有基本数据类型存在,则==判断的是值是否相等
🐇String类
🌳String继承关系
- String实现了Serializable接口,说明String可以串行化,可以在网络中传输;
- String实现了Comparable,说明String对象可以比较;
🌳String本质
- String:private final char value[];
- value不可以指向一个新的地址
1.String 对象用于保存字符串,也就是一组字符序列;“john” 是字符串常量,双引号括起来的字符序列;
2.字符串的字符使用Unicode字符编码,一个字符(包括汉字和字母)占两个字节;
3.String 类有很多构造器,构成构造器的重载;
4.String 是一个final类,不能被其它的类继承;
5. String 中有一个属性private final char value[];用于存放字符串内容;value值不可修改,指的是value指向的地址不可修改;
6. 即value不可以指向一个新的地址,但是单个内存空间的数据是可以改变的;即约束你指向一个新的地址
🌳String对象创建
- 直接赋值 String s = “zzw”;
方式一:先从常量池查看是否有“zzw”数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s最终指向的是常量池的空间地址;
- 调用构造器 String s2 = new String(“zzw”);
方式二:先在堆中创建空间,里面维护了value属性,指向常量池的“zzw”数据空间。如果常量池没有“zzw”,则重新创建;如果有,直接通过value指向,最终指向的是堆中的空间地址。
练习:
- equals()比较的是内容;
- a和b都是指向的常量池;
- a指向的是常量池中的字符串,c指向的堆
- intern()最终返回的是常量池的地址
- p1.name == "zzw"比较的是地址,p1.name指向的地址和"zzw"返回的地址是一个地址,返回true
🌳String特性
1.以下语句创建了几个对象?画出内存布局图。(2个)
String s1 = “hello”; s1 = “haha”;
2.String a = “hello” + “abc”; 创建了几个对象?(1个)
底层优化==>String a = “helloabc”;
3、String a = “hello”; String b = “abc”; String c = a + b; 创建了几个对象?(3个)画出内存布局图。
- 先创建一个 StringBuilder sb = new StringBuilder();
- 执行 sb.append(“hello”);
- 执行 sb.append(“abc”);
- sb. toString();
所以最后一步相当于String c = new String (“helloabc”);
最后c其实是指向堆中的对象(String)value[ ] ->常量池中 “helloabc”>5.内存布局图
多个字符串常量相加底层会优化,只会开辟一个地址;
字符串相加时,如果加数中有字符串变量,则会转换成StringBuilder,最终返回的地址指向堆;
练习:
- 下面代码输出什么,并说明原因;
- 下列程序运行的结果是什么 ,画出内存布局图。
tip:str每次更新都会重新开辟空间;
🌳String常用方法
⭐indexOf方法
- indexOf 获取字符在字符串对象中第一次出现的索引,如果没有,返回-1
⭐substring方法
- substring(5) 从索引5开始截取后面所有的内容
⭐toUpperCase方法
- toUpperCase()转换成大写
⭐concat方法
- concat 拼接字符串, 本身不会改变str的值
⭐replace方法
- replace() 替换字符串的内容,不会改变str的值
⭐split方法
- split() 分割字符串,返回字符数组;如果有特殊字符,需要加入转义字符
⭐toCharArray方法
- toCharArray 将字符串转换成字符数组
⭐compareTo方法
java基础类
- compareTo 比较两个字符串的大小
⭐格式化字符串
- 格式化字符串
🐇StringBuffer类
🌳StringBuffer继承关系
- StringBuffer 的直接父类是AbstractStringBuilder;
- StringBuffer 实现了Serializable接口,说明StringBuffer可以串行化;
🌳StringBuffer本质
- StringBuffer只有四个构造器
- StringBuffer是一个final类,不可以被继承
- StringBuffer的父类 AbstractStringBuilder 中有属性char[] value;
value用于存放字符串,不是final类型;value值可以修改,并且存放在堆中;
🌳String与StringBuffer比较
String:private final char value[];
- String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,原因:private final char value[];
StringBuffer:char[] value;
- StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高,原因:char value[];
🌳StringBuffer构造器
⭐StringBuffer()
- 构造一个不带字符的字符串缓冲区,初始容量为16个字符;
创建一个大小为 16的 char[], 用于存放数据
⭐StringBuffer(int capacity)
- 通过构造器指定 char[] 大小
⭐StringBuffer(String)
- 通过 给一个String 创建StringBuffer,char[] 大小就是str.length + 16
🌳String和StringBuffer转换
- String 转成 StringBuffer
- 方式一:使用StringBuffer构造器
方式二:使用StringBuffer的append方法
- StringBuffer 转成 String
- 方式一:使用StringBuffer的toString方法
方式二:通过String的构造器
🌳StringBuffer常用方法
⭐append方法
- true会被转成字符串,直接输出stringBuffer对象本质是调用toString()方法
System.out.println(stringBuffer);执行流程:
⭐delete方法
- 删除索引>= start && < end范围内的字符串
[start, end),左闭右开
⭐replace方法
- replace(16,20,“蔡文静”),使用“蔡文静”替换 索引为 16-19的字符,[16,20)
⭐indexOf方法
- 查找指定的子串在字符串中第一次出现的索引,如果没有则返回-1;
⭐insert方法
- 在索引为16处插入字符串",",原来索引为9的内容自动后移
⭐length方法
- 返回长度
🌳StringBuffer练习
- 练习1
练习2:
NullPointerException:StringBuffer构造器里不能传一个空值
练习三:将小数-价格的小数点前面每隔三位用逗号分开
改进:
🐇StringBuilder类
- StringBuilder类的直接父类是AbstractStringBuilder
- StringBuilder类实现了Serializable接口,可以串行化
- StringBuilder类被final修饰,不能被继承
- 对象字符序列存在于父类AbstractStringBuilder char[] value中;
- StringBuilder中的方法没有做互斥的处理,没有synchronized关键字,推荐在单线程中使用;
- 如果我们需要对String做大量修改,我们需要使用StringBuffer,不要使用String;原因:
🌳总结
- 如果字符串存在大量的修改,一般使用StringBuffer或者StringBuilder;
- 如果字符串存在大量的修改操作,并处在单线程中,使用StringBuilder;
- 如果字符串存在大量的修改操作,并处在多线程中,使用StringBuffer;
- 如果字符串很少被修改,被多个对象引用,使用String,比如配置信息等;
🐇Math类
- Math常用方法(都是静态方法);abs()方法求绝对值;
- pow(2,3)方法求幂;2^3
- ceil()方法向上取整,返回 >= 参数的最小整数
- floor,向下取整,返回 <= 该参数的最大整数
- round 四舍五入, 等价于Math.floor ( 该参数 + 0.5 );
- sqrt 开平方根
- random()方法, 返回 0 <= x < 1,即[0,1)之间的随即小数
题目:获取a-b之间的一个随机整数,[a,b]
公式:int num = (int)(a + Math.random() * (b-a+1)) ;
- max(参数1,参数2)取最大值
🐇Arrays类
- Arrays类中包含了一系列静态方法,用于管理或操作数组(比如排序或搜索);
⭐Arrays.toString()
- Arrays.toString(),显示数组
⭐Arrays.sort() ->Comparator 定制排序
debug:(1) 进入到Arrays类的sort方法
(2)进入到TimSort类的sort方法
(3)跳转到TimSort类的binarySort方法
(4)在这里调用匿名内部类
注意:public int compare(Object o1, Object o2) 这个方法返回值的正负会影响整个排序结果
2.2 自定义(定制排序/模拟排序):结合冒泡+定制
⭐Arrays.binarySearch()
- Arrays.binarySearch() ;(二叉查找;二分搜索法)
⭐Arrays.copyOf()
- Arrays.copyOf(数组, key) => 数组元素的拷贝,拷贝指定个元素返回到新数组
4.1 拷贝长度 > 原数组长度,添null
4.2 拷贝长度 < 0,报异常
4.3 底层使用的是: System.Array()
⭐Arrays.fill()
- Arrays.fill();数组元素的填充
⭐Arrays.equals()
- Arrays.equals(数组1,数组2); 比较数组1、数组2内容是否完全一致
⭐Arrays.asList()
- Arrays.asList()方法会将一组值转换成一个List集合
asList的运行类型:java.util.Arrays$ArrayList,即Arrays类中的静态内部类
练习:
- 发
🐇System类
- System.exit(0) 表示程序退出;0 表示正常
- System.arraycopy(src, srcPos, dest, destPos, length); 适合底层,一般使用Arrays.copyOf()
src:代表源数组
srcPos:从源数组的哪索引位置开始拷贝
dest:目标数组,即把源数组的元素拷贝到哪个数组
destPos:把源数组的元素拷贝到目标数组的哪个索引位置
length:从源数组拷贝多少个数据到目标数组
- System.currentTimeMillis(); 返回1970年1月1日0时0分0秒到今天的毫秒数(0时区)
- System.gc(); 主动触发垃圾回收机制;
🐇BigInteger类(BigDecimal类)
🌳BigInteger类
- BigInteger 适合比较大的整数
- 当编程中遇到很大的数,long不够用,可以使用BigInteger类
- 在对 BigInteger进行加减乘除的时候,需要使用对应的方法,不能直接+ - * /
🌳BigDecimal类
- 适合保存精度更高的浮点型
- 当我们需要保留一个精度很高的数时,可以使用BigDecimal来解决
- 当我们对BigDecimal进行运算(比如加减乘除)时,需要使用对应的方法,不能直接: + - * /
- 除法可能抛出算术异常:(Non-terminating decimal expansion; no exact representable decimal result.)
解决方案:在调用divide()方法时,指定精度即可 BigDecimal.ROUND.CEILING
如果有无限循环小数,就会保留分子的精度
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/1414.html