目录
三、面向对象
16.Object类
方法
==和equals()
17.String类
注意
构造方法
String的最大长度
String的底层存储结构
字符串的常量池机制
String类的方法
String类的判断功能
String类的获取功能
String类的转换功能
String类拼接
String类的其他功能
18.Math类
19.Random类
20.System类
垃圾回收机制
21.BigInteger类
22.BigDecimal类
23.Date类
24.Calendar类
25.SimpleDateFormat类
26.Arrays类
27.基本类型包装类
基本类型和包装类对应关系
Integer类为例
构造方法
String和int类型的相互转换
JDK5+自动装箱和拆箱
Integer的常量池机制
28.StringBuffer&StringBuilder
StringBuffer
StringBuffer和String的区别
构造方法
成员方法
StringBuffer初始长度和扩容机制
StringBuffer和String的相互转换
StringBuffer和StringBuilder
String,StringBuffer&StringBuilder的区别
API:应用程序编程接口,学习jdk提供的类,就是学习这些类提供的功能
类层次结构的根类,所有类都直接或者间接的继承自该类
所以该类的非私有成员,所有的类都有
public native int hashCode()
//返回该对象的哈希码值,默认情况下,该方法会根据对象的地址来计算(数字),不同对象的hashCode()一般来说不会相同,同一个对象的hashCode()值肯定相同
public final Class getClass()
//返回此Object的运行时类,常用于反射场景,Class类是用来描述类的属性,可以通过Class类中的public String getName(),获取对象的真实类的全名称
public String toString()
//返回的是对象的类名@16进制哈希值,即getClass().getName() + "@" + Integer.toHexString(hashCode()) ,这没什么意义,所以一般都会重写toString()
equals()
//指示其他某个对象是否与此对象相等,默认比较的是地址值,显然没什么意义,因此通常都会重写
==是一个比较运算符号
既可以比较基本数据类型,也可以比较引用数据类型
基本数据类型比较的是值,引用数据类型比较的是地址值
equals方法是一个方法
只能比较引用数据类型
如果没有重写Object类中的equals方法,equals()和==比较引用数据类型无区别
String类不能被继承,public final class String extends Object
字符串本身是常量
String str = "abc";
str = "def"; //此时,"abc"仍然是"abc",并没有改变,但是变成了无用的垃圾,是将"def"赋值 给了引用型变量str
"abc"是常量,一旦生成,值无法改变
str是String类型的引用型变量,它的值,即指向的地址,可以改变
public String()
public String(byte[] bytes),将字节数组转为字符串,字节数组存的是byte类型,如97,转为a(根据平台默认字符集解码)
public String(byte[] bytes, int index, int length),字节数组一部分转为字符串,index从0开始,第三个参数是长度--与获取子串的方法区分
public String(char[] value),字符数组转为字符串
public String(char[] value, int index, int count),字符数组一部分转为字符串,index从0开始,第三个参数是字符数量
public String(String str),字符串常量转为字符串对象
char data[] = {'a','b'}; String str = new String(data) 相当于 String str = "ab"
字符串的内容是由一个字符数组 char[] 来存储的,长度是int,理论上int的范围是2^31 -1
常量池规定length为u2,即两个字节,因此范围就变为了2^16- 1 = 65535
JVM限制范围为65534
jdk8:char[]
jdk9:byte[],优化的原因:char是两字节,很多情况下一个字符只需要一个字节,比如字母,使用char浪费空间
字符串常量池:如果池子中没有该字符串就创建,池子中有就用已有的,不再创建
String str1 = "abc"; //在常量池中创建"abc"
String str2 = "abc"; //直接指向常量池中的"abc"
sop(str1 == str2); //true 比较的是地址,相同
sop(str1.equals(str2)); //true String类的equals()重写了,比较的是值
String str1 = "abc"; //在常量池中创建"abc"
String str2 = new String("abc"); //堆中new一个String对象,对象获取了常量池中的"abc"的副本
sop(str1 == str2); //false 比较的是地址,不同,一个指向常量池,一个指向堆
sop(str1.equals(str2)); //true String类的equals()重写了,比较的是值
String str1 = "abc";
String str2 = "a" + "b" + "c";
sop(str1 == str2); //true java常量优化机制,编译时会自动优化处理常量
sop(str1.equals(str2)); //true
String str1 = "ab";
String str2 = "abc";
String str3 = str1 + "c";
sop(str3 == str2); //false
sop(str3.equals(str2)); //true
String之间用+号串联是通过StringBuilder或StringBuffer类和append()方法+toString()方法实现的
所以这一步实际上所以相当于生成了一个StringBuffer对象,一个String 对象--堆内存,所以是false
equals() 判断值是否相等
equalsIgnoreCase() 忽略大小写判断值是否相等
contains() 判断大字符串是否包含小字符串
startsWith() 判断是否以某字符串开头
endsWith() 判断是否以某字符串结尾
isEmpty() 判断是否为空
int length() 获取长度
char charAt(int index) 获取index处的字符
int indexOf(int ch) ch第一次出现的索引
int indexOf(String str) str第一次出现的索引
int indexOf(int ch, int fromIndex) ch从指定位置开始第一次出现的索引
int indexOf(String str, int fromIndex) strch从指定位置开始第一次出现的索引
lastIndexOf()类似,从后往前检索(最后一次出现的索引)
String subString(int start)
String subString(int start, int end) //左闭右开区间
byte[] getBytes() //字符串转为字节数组,根据平台的编码集,GBK码表1个中文2个字节,特点:第一个字节肯定是负数
char[] toCharArray() //字符串转字符数组
static String valueOf(char[] chs) //字符数组转为字符串
注意:
String类的valueOf()可以将任意类型数据转为字符串,对象也可以,输出的是调用toString()方法的结果
同样的,其他类型转为String也有类似的方法
byte : Byte.parseByte(String s) : 将 s 转换成 byte
double : Double.parseDouble(String s) : 将 s 转换成 double
concat()
String replace(char/String old, new) //替换
trim() //去除两端空格
int compareTo(String str) //按位字典顺序比较,输出按码表值作差的值,相同的是0,长短不一致的,空格算作0
int compareToIgnoreCase(String str) //忽略大小写
用于执行基本数学运算,如初等指数、对数、平方根和三角函数,成员全部是静态的,所以构造方法私有
public static int abs(int a) //绝对值
public static double ceil(double a) //向大取整
public static double floor(double a) //向小取整
public static int max(int a,int b) //取大
public static double pow(double a,double b)//a的b次幂
public static double random() //0.0-1.0之间的随机小数(左闭右开)
public static int round(float a) //四舍五入
public static double sqrt(double a) //开平方
public static double random() //获取随机数,返回带正号的 double 值,该值大于等于 0.0 且小于 1.0
int number = (int)(Math.random()*100)+1; //获取一个1-100之间的随机数
用于产生随机数,产生的随机数由入参(种子)决定,如果用相同的种子创建两个 Random 实例,那么每次重新运行程序生成随机数,都会生成相同的一连串随机数
构造方法
public Random()
public Random(long seed)
成员方法
public int nextInt()
public int nextInt(int n) //给定上限,生成0到n之间的随机数(左闭右开)
包含一些有用的类字段和方法,它不能被实例化
成员方法
public static void gc() //运行垃圾回收器
public static void exit(int status) //终止运行java虚拟机
public static long currentTimeMillis() //获取当前时间与1970.1.1之间的时间差(毫秒值),可以通过首尾获取两次currentTimeMillis()做差得到程序运行的时间
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) //将src数组中srcPos开始的length长度复制到dest数组的destPos起始位置
垃圾回收机制很复杂,此处只是简单描述垃圾回收的一些特点
1.无法人为控制,随机事件对随机垃圾对象进行回收
2.判断对象为垃圾的标准,没有任何引用(关联)
3.垃圾对象在被回收前会运行object类继承来的finalize()来解放内存以外的系统资源,此时垃圾对象会复苏,产生异常,但是虚拟机会进行忽略
4.触发主GC的条件,如何避免(核心是减少内存中的垃圾对象)
1.不要显式System.gc(),虽然是建议,但一般都会运行
2.循环中使用StringBuffer而不是直接操作String,减少内存中的对象
3.能使用基本类型就不用包装类,减少内存中的对象
可以让超过Integer范围内的数据进行运算
构造方法
public BigInteger(String val)
成员方法
public BigInteger add(BigInteger val) +
public BigInteger subtract(BigInteger val) -
public BigInteger multiply(BigInteger val) *
public BigInteger divide(BigInteger val) /
public BigInteger[] divideAndRemainder(BigInteger val) //数组中存商和模(余数)
由于在运算的时候,float类型和double很容易丢失精度,为了能精确的表示、计算浮点数,Java提供了BigDecimal
BigDecimal表示不可变的、任意精度的有符号十进制数
构造方法
public BigDecimal(String val)
成员方法
public BigDecimal add(BigDecimal augend)
public BigDecimal subtract(BigDecimal subtrahend)
public BigDecimal multiply(BigDecimal multiplicand)
public BigDecimal divide(BigDecimal divisor)
表示特定的瞬间,精确到毫秒
构造方法
public Date() //当前时刻
public Date(long date) //传参date意味着从标准时间(1970.1.1)以来指定date毫秒数的时刻,但要注意电脑本机设置的区时,比如传参0,对于东八区,显示的是8点
成员方法
public long getTime() //获取该时间对象对应的毫秒值(System.currentTimeMillis())
public void setTime(long time) //给对象设置毫秒值(距1970)
日历类,是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法
成员方法
public static Calendar getInstance() //获取默认的日历子类,当前时刻
public int get(int field) //传入对应字段,获取对应字段值
public void add(int field,int amount) //对指定字段进行加减操作
public final void set(int year,int month,int date) //设置指定字段的值或者默认顺序设置
日期/时间格式化的抽象类,实现日期和字符串的相互转换
DateFormat是抽象类,所以使用其子类SimpleDateFormat
构造方法
public SimpleDateFormat()
public SimpleDateFormat(String pattern)
成员方法
public final String format(Date date)
public Date parse(String source)
自定义格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); sdf.format(new Date());
pattern的写法
针对数组进行操作的工具类,提供了排序,查找等功能
成员方法
public static String toString(int[] a) //转字符串
public static void sort(int[] a) //排序
public static int binarySearch(int[] a,int key) //二分查找
public static List asList(T... a)
返回对象是一个Arrays内部类,并没有实现集合的修改方法,Arrays.asList 体现的是适配器模式
因为集合中只能存引用型,所以,对于存储非引用型元素的数组,会将整个数组作为一个引用型变量转为集合
作用:将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据
常用操作:用于基本数据类型与字符串之间的转换
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
Integer 类在对象中包装了一个基本类型 int 的值
public Integer(int value)
public Integer(String s) //这里的String,只能是数字字符串,不能是"abc"之类的字符串
int->String
public static String valueOf(int i) //String类提供
public static String toString(int i) //Integer类提供
String->int
public static int parseInt(String s) //Integer类提供,基本数据类型包装类中,只有char类型没有parseInt(String str)方法,char类型显然不能有这样的方法,只能有通过str.toCharArray()将字符串转为字符数组
Integer->int
intValue()
自动装箱:把基本类型转换为包装类类型,不再需要显式使用构造方法
自动拆箱:把包装类类型转换为基本类型,不再需要显式使用intValue()
这样一来,在执行运算时,Integer和int就没有任何区别了
注意事项:
1.在运算时,要保证Integer不为null
2.Integer / Integer,两个Integer类型相除,结果还是整数,不会是小数
-128--127是byte的取值范围,在这个范围内自动装箱不会新创建对象,而是从常量池内获取,因此这个范围内,自动装箱的对象Integer可以直接用==比较大小,相同大小获取的是同一个对象
但是超过这个范围,直接使用==比较大小,就一定会返回false,因为拿到的不是同一个对象,因此应该使用equals()比较,包装类已经重写了equals(),比较的是值,而不是地址
Integer i1 = new Integer(97);
Integer i2 = new Integer(97);
System.out.println(i1 == i2);
System.out.println(i1.equals(i2));
System.out.println("-----------");
//手动装箱,一定新建对象
//fasle
//true
Integer i3 = new Integer(197);
Integer i4 = new Integer(197);
System.out.println(i3 == i4);
System.out.println(i3.equals(i4));
System.out.println("-----------");
//false
//true
Integer i5 = 127;
Integer i6 = 127;
System.out.println(i5 == i6);
System.out.println(i5.equals(i6));
System.out.println("-----------");
//自动装箱,-128--127之间,同样大小不会新建对象
//true
//true
Integer i7 = 128;
Integer i8 = 128;
System.out.println(i7 == i8);
System.out.println(i7.equals(i8));
线程安全的可变字符序列
String是一个不可变的字符序列
StringBuffer是一个可变的字符序列,底层是定长字符数组char[capacity],长度是int类型,理论上最大长度即为int的最大值,即2^31-1
public StringBuffer() //默认生成容量为16个字符的字符缓冲区
public StringBuffer(int capacity) //可以指定容量
public StringBuffer(String str) //可以直接把String塞进缓冲区,此时容量为str.length() + 16,塞入其他StringBuffer,StringBuilder,String子类对象也可以
sb.length() //容器中字符个数
sb.capacity() //容器容量
public StringBuffer append(String str) //可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身
public StringBuffer insert(int offset,String str) //在指定位置把任意类型的数据插入到字符串缓冲区里面,并返回字符串缓冲区本身
public StringBuffer deleteCharAt(int index) //删除指定位置的字符,并返回本身
public StringBuffer delete(int start,int end) //删除从指定位置开始指定位置结束的内容,并返回本身
public StringBuffer replace(int start,int end,String str) //从start开始到end用str替换
public StringBuffer reverse() //字符串反转
public String substring(int start) //从指定位置截取到末尾
public String substring(int start,int end) //截取从指定位置开始到结束位置,包括开始位置,不包括结束位置
public char charAt(int index) //返回指定位置的char,返回的是基本数据类型char,不是包装类Character,不可以使用equals()去把String与char进行比较,那样一定是false,用 == 比较两个char
初始长度:无参构造16,有参构造16+str.length()
扩容机制:扩容是新建数组+复制原数组数据+追加新内容
一次追加长度超过当前容量,则会按照 当前容量*2+2 扩容一次
一次追加长度不仅超过初始容量,而且按照 当前容量*2+2 扩容一次也不够,其容量会直接扩容到与所添加的字符串长度相等的长度
String->StringBuffer:通过StringBuffer的构造方法
StringBuffer->String:通过toString()方法
相同:都是AbstractStringBuilder的子类,用法几乎相同
区别:StringBuffer是jdk1提供,是线程安全的,效率低;StringBuilder是jdk5提供,是线程不安全的,效率高
String是一个不可变的字符序列
StringBuffer&StringBuilder是可变的字符序列
String和StringBuffer分别作为参数传递:String作为参数传递,方法外的值不会改变;StringBuffer&StringBuilder进行append()后方法外的值会改变