尴尬我好像又鸽了好多天,最近有期末作业要搞,搞着搞着就鸽了
Object
java.lang.Object 类是所有类的根,所有类都直接(当没有显示继承时自动继承Object类)或间接继承了Object类
Object类中有11个方法
修饰语与返回类型 | 方法名 | 作用 |
---|---|---|
protected Object() | clone() | 创建并返回此对象的副本。 |
boolean | equals(Object obj) | 指示某个其他对象是否“等于”此对象。 |
Class<?> | getClass () | 返回此对象的运行时类。 |
int | hashCode () | 返回对象的哈希代码值。 |
protected void | finalize() | 当垃圾回收确定不再有对对象的引用时,由对象上的垃圾回收器调用。 |
void | toString() | 将对象转换成字符串 |
void | notitfy () | 唤醒正在该对象的监视器上等待的单个线程。 |
void | notifyAll() | 唤醒在该对象监视器上等待的所有线程。 |
void | wait() | 使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法。 |
void | wait(long timeout) | 使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法,或者经过指定的时间量。 |
void | wait(long time,int nanos) | 使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法,或其他某个线程中断当前线程,或经过一定的实时时间。 |
常用方法:
-
getClass()——返回对象运行时类的Class对象,表示运行时类,可以认为是字节码文件,主要用于反射
Object类中多个方法都是被
native
关键字修饰的- 被
native
修饰的方法,称为本地方法 - 该方法的方法体由非java语言实现,主要用来调用本地的底层语言,如c或c++
- 定义该方法时并不提供方法体,而是使用外部的非java语言实现
- 被
-
equals()
equals()和==的区别:
- ==判断是否引用同一个对象,比较的是栈中的值
- equals如果没有被重写,则默认和==没有区别,因为Object的equals()就是使用==来判断的
- 如果重写了equals,这按重写后的比较规则进行比较
自定义类可以重写equals()方法来实现第特定字段的等值判断
(PS:在研究String的equal和==的区别比较特殊,如果没有使用new默认会从常量值寻找/创建一个字符串,并将地址指向创建的对象中,因此此时使用equal和==都可以返回True。但如果使用new这默认新开个地址)
参考链接:https://blog.csdn.net/qq_36522306/article/details/80550210
-
hashCode()——返回对象的hashCode值,即哈希码值
- hashCode是为了支持数据结构的哈希表hash table
-
如果没有重写该方法,默认返回的是对象的内存地址
- 重写equals()方法时,务必要重写hashCode方法
特性:
- 多次调用同一个对象的hashCode方法,必须返回相同的值
-
如果两个对象的equals比较为true,则两个对象的hashCode值也应该相同
- 如果两个对象的equals比较为false,不强制要求两个hashCode值不相同,但为不容对象产生不同的hashCode值可以提升哈希表的性能
-
toString()——将对象转换为字符串表示形式
- 当直接输出对象时,会自动调用对象的toString()方法,本质上输出的是toString()方法的返回值
- 如果没有重写该方法,默认返回值:
类全民@十六进制的hashCode值
- 通过重写该方法,输出对象时可以返回更易读的信息,便于查看结果,一般用于测试、
-
clone()——用于克隆对象
被克隆的要求:
- 必须重写clone()方法,且要调用super.clone()方法
- 类必须实现
Cloneable
接口,表示该类可以被克隆、
浅克隆和深克隆:
-
浅克隆——从Object继承的clone()方法默认是浅克隆,只克隆对象本身,不克隆它应用的对象,即只克隆第一层所有的对其他对象的引用仍然指向原来的对象
-
深克隆——把要克隆的对象所引用的其他对象都克隆一遍;所有的对其他对象的引用都将指向被克隆的新对象;需要自己实现,对所有引用的其他对象进行再次克隆
参考链接:
-
finalize()——该方法不需要程序员手动调用,由垃圾回收器自动调用
垃圾回收机制:
- JVM中存在有一个守护进程,叫做 GC :garbage collector 垃圾回收器
- gc的作用:
- 每个对象上,都会有一个存在int类型的变量,叫做引用计数器;每当有一个引用指向该对象时,引用计数+1;每当有一个引用不在指向该对象时,引用-1;当计数值为0时,gc认为该对象为垃圾;gc在根据算法对垃圾进行回收,释放资源;当gc执行回收时,gc会自动调用finalize()方法;也可以通过
System.gc()
就,建议JVM进行垃圾回收
String
java.lang.String 字符串就是一个字符序列,由多个字符组成,是Java中最常用的类型
public final class String
implements java.io.Serializable,Comparable<String>,CharSequence
创建字符串的方式:
- 直接创建字符串
- 使用构造方法创建
常用方法:
方法名 | 作用 |
---|---|
length | 获取字符串长度 |
IndexOf | 获取指定子串第一次出现的位置,如果找不到则返回-1 |
lastIndexOf | 获取指定子串最后一次出现的位置 |
substring | 获取指定索引范围内的子串,即截取字符串,范围[beginIndex,endIndex),左闭右开 |
charAt | 获取指定索引位置的字符 |
concat | 字符串拼接,很少使用,一般直接使用+进行拼接 |
startsWith | 判断是否以指定的子串开头 |
endsWith | 判断是否以指定子串结尾 |
contains | 判断是否包含指定子串 |
isEmpty | 判断是否为空字符串 |
equals | 判断值是否相等 |
equalsIgnoreCase | 判断是否相等,忽略大小写 |
toUpperCase | 转换为大写 |
toLowerCase | 转换为小写 |
replace | 替换 |
trim | 去掉字符串首尾的空格 |
split | 将字符串分割为数组 |
toCharArray | 将字符串转换为字符数组 |
getBytes | 将字符串转换为字节数组 |
join | 将多个元素与指定分隔符拼接为字符串,jdk8中新增方法,静态方法String.join() |
字符集
字符Character:是各种文字和符号的总称,包括各国文字,标点符号,图形符号,数字等
字符集Charset:是多个字符的集合,字符集种类很多,每个字符集包含的符号个数不同
常见字符集:ASCII,ISO-8859-1,GB2312,GBK,UTF-8 (Windows系统默认使用GBK,Linux和MacOS系统默认使用UTF-8)
System.out.println("当前系统使用的字符集: "+System.getProperty("file.encoding"));
System.out.println("当前JVM使用的字符集: "+Charset.defaultCharset());
由于计算机底层使用二进制,只认识0和1,所以在处理各种字符时,需要对字符进行编码和解码,以便计算机能够识别和存储(编码:将字符串转换为字节数组 解码:将字节数组转换为字符串)
正则表达式
正则表达式是一门独立的语言,有自己的语法,用于检测指定字符串是否符合规则(正则表达式就是用来定义规则的)
规则
示例 | 作用 |
---|---|
a | 只能是a |
a|b | 只能是a或b |
a{5} | 只能是a,并且有5位 |
a{5,} | 只能是a,至少有5位 |
a{5,7} | 只能是a,5到7位 |
a* | 只能是a,0到多位,即可有可无 |
a+ | 只能是a,1到多位,即至少有1位 |
a? | 只能是啊,0到1位 |
[a-g]{5} | 只能是a到g,并且有5位 |
[a-zA-Z]{5} | 只能是字母,忽略大小写,并且有5位 |
[0-9a-zA-z]{2,} | 只能是数字,字母,至少有2位 |
. | 任意一个字符 |
\d | 数字,\表示正则转义符 |
\D | 非数字 |
\w | 数字,字母,下划线 |
\W | 非(数字,字母,下划线) |
\s | 空格 |
\S | 非空格 |
\n | 回车 |
\t | 制表符 |
用法:
方法名 | 作用 |
---|---|
matches | 判断字符串是否匹配某个规则 |
replaceAll | 作用和replace一样,区别在于支持正则 |
replaceFirst | 作用和replaceAll一样,区别是只替换第一个 |
split | 使用正则,将字符串分割为数组 |
不变性
字符串的值一旦确定,则不可修改
不可修改
指的是内存中的值不能再修改,不是变量不能修改
常量池
- jdk1.6中,常量池在方法区的PermGen Space永久代中(就是一个永久保存区域)
- jdk1.7中,常量池在堆内存中
- jdk1.8中,常量池在元空间中,和堆相独立
StringBuffer和StringBuilder
- String是不可变字符串,不可修改
- 频繁对String进行修改时会在内存中产生许多对象,垃圾数据
- Stirng类中提供了许多方法,但没
增删改
等操作的方法
如果需要频繁对字符串进行修改操作,建议使用StringBuffer和StringBuilder,它们是可变字符串
区别:
StringBuffer
-
线程安全(多个人同时访问一个字符串,不会出现问题)
-
效率低
StringBuilder
- 线程不安全(多个人同时访问一个字符串,可能会出现问题)
- 效率高
性能对比
StringBuilder sd=new StringBuilder(); long start = System.currentTimeMillis(); for (int i = 1; i <= 100000; i++) { // str += "hello"; sd.append("hello"); } long end = System.currentTimeMillis(); System.out.println("StringBuilder花费的时间:" + (end - start) + "ms"); //StringBuilder花费的时间:18ms StringBuffer sb = new StringBuffer(); long start = System.currentTimeMillis(); for (int i = 1; i <= 100000; i++) { // str += "hello"; sb.append("hello"); } long end = System.currentTimeMillis(); System.out.println("StringBuffer花费的时间:" + (end - start) + "ms"); //StringBuffer花费的时间:13ms String s = ""; long start = System.currentTimeMillis(); for (int i = 1; i <= 100000; i++) { // str += "hello"; s+="hello"; } long end = System.currentTimeMillis(); System.out.println("String花费的时间:" + (end - start) + "ms"); //String花费的时间:4044ms
包装类
基本数据类型功能比较简单,不具有面向对象的特性。因此Java为每个基础数据类型都提供了一个对应的包装类,使其具有面向对象的特性。
基本数据类型 | 对应的包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
基本类型和包装类的转换
在JDK1.5以前,需要手动装箱和拆箱,JDK1.5及以后支持自动装箱和拆箱(将基本数据类型转换为包装类称为装箱,将包装类转换为基本数据类型称为拆箱)
基本数据类型和Stirng的转换:
//将基本数据类型转String
int a=9;
//利用包装类进行转换
String str=Integer.toString(a);
System.out.println(str);
//拼接空字符串(常用)
System.out.println(a+"");
//利用包装类转换成2进制形式,然后转成字符串
System.out.println(Integer.toBinaryString(a));
//利用包装类转换成8进制形式,然后转成字符串
System.out.println(Integer.toOctalString(a));
//利用包装类转换成16进制形式,然后转成字符串
System.out.println(Integer.toHexString(a));
//字符串形式的数值
String b="11";
//将字符串强制转换为Integer类型,然后再解包为int类型,可以有2个参数,第一个参数为字符串,第二个参数为进制,默认为10
int i=Integer.parseInt(b);
System.out.println(Integer.parseInt(b,2));
System.out.println(Integer.parseInt(b,8));
其他类
Date
java.util.Date
表示日期,底层使用long类型表示日期(long类型的值是当前时间的毫秒值,是基于1970年1月1里 0时0分0秒
的差值,这个时间被认为是计算机的起始时间——纪元时间)
常用方法(Data类中有多个构造方法时过时的,不建议使用)
Date date=new Date();
//getYear(),getMonth(),getDate(),getHours()等,都已过时
//getTime()获取毫秒值
System.out.println(date.getTime());
//setTime() 设置毫秒值
date.setTime(6666);
System.out.println(date);
Date d1=new Date(222);
Date d2=new Date(111);
//after()判断某个日期是否在指定日期之后
System.out.println(d1.after(d2));
//before()判断某个日期是否在指定日期之前
System.out.println(d1.before(d2));
//a.compareTo()对日期进行比较,如果a大,返回1;小返回-1;相等返回0
Date d3=new Date(111);
System.out.println(d1.compareTo(d2));
System.out.println(d2.compareTo(d1));
System.out.println(d2.compareTo(d3));
Data和String的转换
使用java.text.SimpleDateFormat
日期格式化类,继承自DateFormat:
//将日期转换为字符串
Date date=new Date();
//1.创建SimpleDateFormat对象,指定目标格式
DateFormat df=new SimpleDateFormat("E yyyy年MM月dd日 HH:mm:ss");
//2.调用format()进行格式化
String str=df.format(date);
System.out.println(str);
//将字符串转换为日期
String s="2020年10月30日";
//1.创建SimpleDateFormat对象,指定字符串的日期格式
DateFormat df2=new SimpleDateFormat("yyyy年MM月dd日");
Date d=df2.parse(s);
System.out.println(d);
日期格式
字符 | 描述 | 实例 |
---|---|---|
G | Era 指示器 | AD |
y | 四位数表示的年 | 2001 |
M | 一年中的月 | July 或 07 |
d | 一月中的第几天 | 10 |
h | 带有 A.M./P.M. 的小时(1~12) | 12 |
H | 一天中的第几小时(0~23) | 22 |
m | 一小时中的第几分 | 30 |
s | 一分中的第几秒 | 55 |
S | 毫秒 | 234 |
E | 一周中的星期几 | Tuesday |
D | 一年中的第几天 | 360 |
F | 所在的周是这个月的第几周 | 2 (second Wed. in July) |
w | 一年中的第几周 | 40 |
W | 一月中的第几周 | 1 |
a | A.M./P.M. 标记 | PM |
k | 一天中的第几小时(1~24) | 24 |
K | 带有 A.M./P.M. 的小时(0~11) | 10 |
z | 时区 | Eastern Standard Time |
’ | Escape for text | Delimiter |
Calendar
java.util.Calendar
表示日历,用于日期的运算和取值
Calendar是一个抽象类,不能通过new来创建,使用静态方法getInstance()获取一个实例
常用方法:
//创建一个Calendar实例
Calendar c=Calendar.getInstance();
System.out.println(c.getClass());
//getTime(),将Calendar转换为Date
Date d=c.getTime();
System.out.println(d);
//setTime()设置时间为指定的Date
c.setTime(new Date(22222222));
System.out.println(c.getTime());
//get()获取日期的指定字段
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.MONTH)+1);
System.out.println(c.get(Calendar.DATE));
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.DAY_OF_WEEK));
System.out.println(c.get(Calendar.DAY_OF_YEAR));
System.out.println(c.get(Calendar.HOUR));
System.out.println(c.get(Calendar.HOUR_OF_DAY));
System.out.println(c.get(Calendar.MINUTE));
System.out.println(c.get(Calendar.SECOND));
System.out.println(c.get(Calendar.MILLISECOND));
c.set(2020,11,2);
c.set(2020,Calendar.FEBRUARY,2,18,38,59);
c.set(Calendar.YEAR,2020);
c.set(Calendar.DATE, 2);
System.out.println(c.getTime());
c.add(Calendar.YEAR, 2);
c.add(Calendar.DATE, 3);
c.add(Calendar.HOUR, 1);
System.out.println(c.getTime());
c.clear();
System.out.println(c.getTime());
System.out.println(c.getTimeInMillis());
System.out.println(System.currentTimeMillis());
Math
java.lang.Math
用于执行数字运算,Math类中所有的方法都是静态方法
System.out.println(Math.PI);
System.out.println(Math.E);
double a=3.758;
//round()四舍五入
System.out.println((int)a);
//floor()向下取整
System.out.println(Math.floor(a));
// ceil()返回大于等于参数的最小整数
System.out.println(Math.ceil(a));
// abs()绝对值
System.out.println(Math.abs(-5));
// pow()求次方
System.out.println(Math.pow(2,5));
// random()产生一个[0,1)的随机浮点数
System.out.println(Math.random());
System.out.println((int)(Math.random()*100));
System.out.println((int)(Math.random()*61)+20);
System.out.println((int)(Math.random()*61)+20);
Random
java.util.Random
用于生成随机数
//创建一个Random实例,随机数生成器
Random r=new Random();
//nextInt()生成一个随机整数
System.out.println(r.nextInt());
System.out.println(r.nextInt(100));
System.out.println(r.nextInt(61)+20);
//nextDouble生成一个[0,1)之间的随机浮点数,相当于Math.random()
System.out.println(r.nextBoolean());
//nextBoolean()生成一个随机布尔值
System.out.println(r.nextBoolean());
枚举,泛型和内部类
枚举
枚举类型是JDK1.5引入的新类型,本质上就是一个类,是自定义的数据类型(适用于有限个数的取值)
作用:
-
用来限制可能错的取值个数
-
降低出错的几率
-
提高代码的可读性和可扩展性
用法:使用enum关键字(enumeration的缩写),定义方式:
public enum 枚举类型名()
特性:
- 枚举类型中可以包含属性,方法,构造方法等
- 枚举方法必须是私有的,不允许在外部创建对象,只能在内部创建对象
- 在内部创建枚举对象时必须位于类的第一行
- 在内部创建枚举对象时本质上就是在调用构造方法,如果调用的是无参构造方法,可以省略()
- 可以创建多个枚举对象,多个对象之间以逗号隔开
- 枚举对象也称为枚举项,本质上是静态常量,通过
枚举类型名.枚举项
的方式访问,同时在命名上所有字母大写
泛型
Generic Type泛型本质是参数化类型,所操作的数据类型被指定为一个参数,在使用时确定此类型。(在定义是不知道具体的类型,在使用时要指定具体的类型,类似于参数,所以称为参数化类型)
分类:泛型类,泛型接口,泛型方法
用法:
泛型类:
- 表示类中有一个未知的类型
- 定义方式:
public class 类名<T>{}
,T表示的是一种类型,是泛型的类型参数,可以使用任意标识,一般使用T,E,K,V等 - 可以在类内部使用T,表示一个对象的类型
- 在使用类时需要在类名后通过
<类型>
指定具体的类型 - 在JDK7中支持泛型的类型推断:
类名<类型> 对象名=new 类名<>();
泛型接口:
- 表示接口中有一个未知的类型
- 定义方式:
public interface 接口名<T>()
- 可以在接口内部使用T,表示一个对象的类型
- 在使用接口时需要在接口名后通过
<类型>
指定具体的类型
泛型方法:
- 表示方法中有一个未知的类型
- 定义方式:
public 修饰符 <T> 返回值类型 方法名()
- 可以在方法内部使用T,表示一个对象的类型
- 在调用方法时指定具体的类型
- 应用场景:如果类和接口没有定义泛型,但是想在方法中使用泛型(如方法接收一个泛型参数),此时可以将该方法定义为泛型方法
特性:
- 泛型的类型参数必须是引用类型,不能是基本类型
- 泛型的类型参数可以有多个,即多个泛型参数
- 可以使用泛型通配符
- <? extends T > 限定类型的上线,参数类型必须是T或T的子类
- <? super T> 限定类型的下限,参数类型必须是T或T的父类
内部类
定义在另一个类里面的类,称为内部类Inner Class(包含内部类的类,称为外部类Outer Class)
分类:1.成员内部类 2.局部内部类 3,静态内部类 4.匿名内部类(最常用)
用法:
成员内部类:
-
在外部类中访问内部类:可以访问内部类的所有成员,包含private修饰的成员
-
在外部类外访问内部类:不能访问内部的private修饰的成员
-
在内部类中访问外部类:直接访问
(内部类的命名:
外部类$内部类名.class
)
局部内部类(使用static修饰的成员内部类)
匿名内部类
没有名字的内部类,因为此类只需要使用一次,所以没有起名字的必要,创建匿名内部类时,必须作为new语句的一部分来声明:
接口名/类 对象名=new 接口名/类(){//匿名内部类};
必须是引用类型,不能是基本类型
- 泛型的类型参数可以有多个,即多个泛型参数
- 可以使用泛型通配符
- <? extends T > 限定类型的上线,参数类型必须是T或T的子类
- <? super T> 限定类型的下限,参数类型必须是T或T的父类
内部类
定义在另一个类里面的类,称为内部类Inner Class(包含内部类的类,称为外部类Outer Class)
分类:1.成员内部类 2.局部内部类 3,静态内部类 4.匿名内部类(最常用)
用法:
成员内部类:
-
在外部类中访问内部类:可以访问内部类的所有成员,包含private修饰的成员
-
在外部类外访问内部类:不能访问内部的private修饰的成员
-
在内部类中访问外部类:直接访问
(内部类的命名:
外部类$内部类名.class
)
局部内部类(使用static修饰的成员内部类)
匿名内部类
没有名字的内部类,因为此类只需要使用一次,所以没有起名字的必要,创建匿名内部类时,必须作为new语句的一部分来声明:
接口名/类 对象名=new 接口名/类(){//匿名内部类};