关于java常用类记录理解
常用类
一.Math类
常用方法
- Math.random()//随机取一个[0.0,1.0)的数
- Math.abs(a) //a的绝对值
- Math.ceil(9.1)//向上取值10.0
- Math.floor(9.9)//向下取值9.0
- Math.round(3.4)//四舍五入
- Math.max(a,b)//输出大值
- Math.min(a,b)//输出小值
二.Random类
常用方法
- (int) nextInt()//生成随机整数
- (double)nextDouble()//生成随机double数
- (double)nextGaussian()//生成一个高斯分布的double值
三.String类
- final修饰String类,String类不能被继承。
- String底层是一个char类型数组去一个个存储字符。
常用方法
-
length()//输出字符长度
-
(boolean)isEmpty() //字符串是否为空
-
charAt(n)//返回字符串底层数组下标为n的一个字符
-
(boolean)equals(Obj)
public boolean equals(Object anObject) { //先直接比较地址值是否相同 if (this == anObject) { return true; } //如果地址值不同时,再去比较字符的值是否相同 if (anObject instanceof String) {//当出入对象不是字符串类型,不用比较,直接不相等 String anotherString = (String)anObject; int n = value.length; //如果长度一样,才可能相等,否则肯定不同 if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }这其中涉及到了一个地址的问题,下面给出一个具体实例
String s="abc"; String s2="abc"; String s3=new String("abc"); System.out.println(s==s3);//false System.out.println(s==s2);//true System.out.println(s.equals(s3));//true代码中的,利用==‘’去判断两个变量是否相同,就只单纯比较它们的地址,如果地址不同返回false;
*s和s2实际上相当于两个变量,那创建s2后,s2指向的是“abc”所在的地址,所以s和s2都指向同一地址,自然判断相等;
*而s3是new新建的String类型对象,相当于多开辟了一段空间
在s3里存放着“abc”,这样s和s3的地址不同,“==”操作,两者并不相同;
*equals方法源码上面写到,先判断两者地址,当不相同后继续一个个计较两者内部的字符是否相同,因为s3,s地址内都放着“abc”,所以equals方法返回ture;
- equals和==‘’的区别在于==比较两者地址是否相同,而equals会经过重写,对于固有类型判断地址,对于对象不仅可以判断对象地址,还可以比较各自内部进行比较。

-
(int)compareTo(String)
*第一种情况是当两个字符串中的字符不同,则返回前者-后者的ASCII码值;例a=“abc”,b=“acc”,返回’b’-‘c’=98-99=-1
*第二种情况是当两个字符串字符相同但不等长,则返回前者长度-后者长度;例a=“abcds”,b=“abc”,返回len(a)-len(b)=5-3=2
*第三种情况是当两字符串相同时,返回0.
-
substring(int)//字符串截取,类似python切片[a,b)
-
concat(String)//字符串的拼接
-
replace(char,char)//后者字符替换前者字符
-
split(String)//字符串切割,以String切割,例split(“,”),以逗号切割。
-
toUpperCase()/tpLowerCase();//字母大小写转化
-
trim()//取出首尾空格
-
toString(a)//返回字符串a
-
Valueof(Obj)//其他类型转String类型
String内类分析
//java中存在编译优化,实际上s1-s5编译后都是“abc”
String s1="abc";
String s2="ab"+"c";
String s3="abc"+"";
String s4="a"+"b"+"c";
String s5="a"+"bc";
//new 新对象,这里通过新建对象等于“abc”
String s6=new String("abc");
//有变量参与的字符串拼接,编译就不会简单的合并“abc”
String a="ab";
String s7=a+"c"; //s7="abc"的方式,与上面s1-s5不同
下面是s1-s6的内存分析图,由于在上面equals方法上详细解释过,这里就不多叙述了。

四.String,StringBuilder,StringBuffer分析(面试)
*字符串可分为:不可变字符串(String)
可变字符串(StringBuilder,StringBuffer)
1.StringBuilder类
- 底层存储方式仍是char数组,count指数组被使用的长度。

上图是对StringBuilder()底层存储逻辑的简单展示。
-
首先图中语句使StringBuilder方法定义了一个len(“abc”)+16长度的数组,count负责监测数组位置占用个数,开始是3.
-
然后在不断的给str对象添加字符后,不断更新count值
-
当count大于该数组长度,说明添加字符长度过大,超过数组,这时
*若添加字符后总长度小于len(char)<<1+2时,扩容长度为len(char)<<1+2;(因为这样扩容每次多扩一些,可以减少扩容次数,避免频繁扩容)扩容后,把旧数组内容复制给新数组并添加新的元素,value指针指向新数组,就数组丢弃;
*若添加字符后总长度大于len(char)<<1+2时,直接扩容到能放下全部字符为止,但是总长度要小于int类型最大值。
-
通过以上步骤,就完成了StringBuilder类的动态数组实现的方式了。
2.字符串可变与不可变的实质
可变与不可变的定义就在于,是否能在地址不变的情况下改变指向的字符串
String对象向改变字符串内容只能指向新的字符串地址。线程安全。
StringBuilder上节图片显示出,无论底层数组是否扩容,对象指向的地址不变,只是变的地址中的数组。线程不安全,但效率高。


最后
文中部分图片借鉴马士兵赵珊珊老师的视频讲解,仅供学习理解使用。

被折叠的 条评论
为什么被折叠?



