JAVA潜心修炼五天——第3天

尴尬我好像又鸽了好多天,最近有期末作业要搞,搞着搞着就鸽了
在这里插入图片描述

Object

java.lang.Object 类是所有类的根,所有类都直接(当没有显示继承时自动继承Object类)或间接继承了Object类

Object类中有11个方法

修饰语与返回类型方法名作用
protected Object()clone()创建并返回此对象的副本。
booleanequals(Object obj)指示某个其他对象是否“等于”此对象。
Class<?>getClass ()返回此对象的运行时类。
inthashCode ()返回对象的哈希代码值。
protected voidfinalize()当垃圾回收确定不再有对对象的引用时,由对象上的垃圾回收器调用。
voidtoString()将对象转换成字符串
voidnotitfy ()唤醒正在该对象的监视器上等待的单个线程。
voidnotifyAll()唤醒在该对象监视器上等待的所有线程。
voidwait()使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法。
voidwait(long timeout)使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法,或者经过指定的时间量。
voidwait(long time,int nanos)使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法,或其他某个线程中断当前线程,或经过一定的实时时间。

常用方法:

  1. getClass()——返回对象运行时类的Class对象,表示运行时类,可以认为是字节码文件,主要用于反射

    Object类中多个方法都是被native关键字修饰的

    • native修饰的方法,称为本地方法
    • 该方法的方法体由非java语言实现,主要用来调用本地的底层语言,如c或c++
    • 定义该方法时并不提供方法体,而是使用外部的非java语言实现
  2. equals()

    equals()和==的区别:

    • ==判断是否引用同一个对象,比较的是栈中的值
    • equals如果没有被重写,则默认和==没有区别,因为Object的equals()就是使用==来判断的
    • 如果重写了equals,这按重写后的比较规则进行比较

    自定义类可以重写equals()方法来实现第特定字段的等值判断

    (PS:在研究String的equal和==的区别比较特殊,如果没有使用new默认会从常量值寻找/创建一个字符串,并将地址指向创建的对象中,因此此时使用equal和==都可以返回True。但如果使用new这默认新开个地址)

    参考链接:https://blog.csdn.net/qq_36522306/article/details/80550210

  3. hashCode()——返回对象的hashCode值,即哈希码值

    • hashCode是为了支持数据结构的哈希表hash table
  • 如果没有重写该方法,默认返回的是对象的内存地址

    • 重写equals()方法时,务必要重写hashCode方法

    特性:

    • 多次调用同一个对象的hashCode方法,必须返回相同的值
  • 如果两个对象的equals比较为true,则两个对象的hashCode值也应该相同

    • 如果两个对象的equals比较为false,不强制要求两个hashCode值不相同,但为不容对象产生不同的hashCode值可以提升哈希表的性能
  1. toString()——将对象转换为字符串表示形式

    • 当直接输出对象时,会自动调用对象的toString()方法,本质上输出的是toString()方法的返回值
    • 如果没有重写该方法,默认返回值:类全民@十六进制的hashCode值
    • 通过重写该方法,输出对象时可以返回更易读的信息,便于查看结果,一般用于测试、
  2. clone()——用于克隆对象

    被克隆的要求:

    • 必须重写clone()方法,且要调用super.clone()方法
    • 类必须实现 Cloneable接口,表示该类可以被克隆、

    浅克隆和深克隆:

    • 浅克隆——从Object继承的clone()方法默认是浅克隆,只克隆对象本身,不克隆它应用的对象,即只克隆第一层所有的对其他对象的引用仍然指向原来的对象

    • 深克隆——把要克隆的对象所引用的其他对象都克隆一遍;所有的对其他对象的引用都将指向被克隆的新对象;需要自己实现,对所有引用的其他对象进行再次克隆

在这里插入图片描述

参考链接:

https://www.cnblogs.com/liqiangchn/p/9465186.html

  1. 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为每个基础数据类型都提供了一个对应的包装类,使其具有面向对象的特性。

基本数据类型对应的包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

基本类型和包装类的转换

在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);
日期格式
字符描述实例
GEra 指示器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
aA.M./P.M. 标记PM
k一天中的第几小时(1~24)24
K带有 A.M./P.M. 的小时(0~11)10
z时区Eastern Standard Time
Escape for textDelimiter

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,表示一个对象的类型
  • 在调用方法时指定具体的类型
  • 应用场景:如果类和接口没有定义泛型,但是想在方法中使用泛型(如方法接收一个泛型参数),此时可以将该方法定义为泛型方法
特性:
  • 泛型的类型参数必须是引用类型,不能是基本类型
  • 泛型的类型参数可以有多个,即多个泛型参数
  • 可以使用泛型通配符
    1. <? extends T > 限定类型的上线,参数类型必须是T或T的子类
    2. <? super T> 限定类型的下限,参数类型必须是T或T的父类

内部类

定义在另一个类里面的类,称为内部类Inner Class(包含内部类的类,称为外部类Outer Class)

分类:1.成员内部类 2.局部内部类 3,静态内部类 4.匿名内部类(最常用)

用法:
成员内部类:
  • 在外部类中访问内部类:可以访问内部类的所有成员,包含private修饰的成员

  • 在外部类外访问内部类:不能访问内部的private修饰的成员

  • 在内部类中访问外部类:直接访问

    (内部类的命名:外部类$内部类名.class

局部内部类(使用static修饰的成员内部类)
匿名内部类

没有名字的内部类,因为此类只需要使用一次,所以没有起名字的必要,创建匿名内部类时,必须作为new语句的一部分来声明:

接口名/类 对象名=new 接口名/类(){//匿名内部类};

必须是引用类型,不能是基本类型

  • 泛型的类型参数可以有多个,即多个泛型参数
  • 可以使用泛型通配符
    1. <? extends T > 限定类型的上线,参数类型必须是T或T的子类
    2. <? super T> 限定类型的下限,参数类型必须是T或T的父类

内部类

定义在另一个类里面的类,称为内部类Inner Class(包含内部类的类,称为外部类Outer Class)

分类:1.成员内部类 2.局部内部类 3,静态内部类 4.匿名内部类(最常用)

用法:
成员内部类:
  • 在外部类中访问内部类:可以访问内部类的所有成员,包含private修饰的成员

  • 在外部类外访问内部类:不能访问内部的private修饰的成员

  • 在内部类中访问外部类:直接访问

    (内部类的命名:外部类$内部类名.class

局部内部类(使用static修饰的成员内部类)
匿名内部类

没有名字的内部类,因为此类只需要使用一次,所以没有起名字的必要,创建匿名内部类时,必须作为new语句的一部分来声明:

接口名/类 对象名=new 接口名/类(){//匿名内部类};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值