内部类、IO流、常用类总结

一、内部类

Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。其可分为成员内部类、局部内部类、匿名内部类

1.成员内部类

1.1 成员内部类的理解

成员内部类作为外部类的成员:

  • 可以调用外部类的结构
  • 可以被static修饰
  • 可以被4种不同的权限修饰

成员内部类作为一个类:

  • 其类里面可以定义属性、方法、构造器等
  • 其可以被final修饰,表示此类不能被继承。言外之意,不使用ginal,就可以被继承
  • 其可以被abstract修饰

1.2 如何创建成员内部类对象?(静态的,非静态的)

//创建静态的Dog内部类的实例(静态的成员内部类)
Person.Dog. dog = new Person.Dog();

//创建非静态的Bird内部类的实例(非静态的成员内部类)
//Person p = new Person();错误的
Person p = new Person();
Person.Bird bird = p.new Bird();

1.3 如何在成员内部类中调用外部类的结构?

class Person{
	String name = "小明";
	public void eat(){}
	//非静态成员内部类
	class Bird{
		String name = "杜鹃";
		public void display(String name){
			System.out.println(name);//方法的形参
			System.out.println(this.name);//内部类的属性
			System.out.println(Person.this.name);//外部类的属性
			Person.this.eat();
		}
	}
}

2.局部内部类

2.1 局部内部类的使用

//返回一个实现了Comparable接口的类的对象
public Comparable getComparable(){
	//创建一个实现了Comparable接口的类:局部内部类
	//方式一:
//	class MyComparable implements Comparable{
//		@Override
//		public int compareTo(Object o){
//			return 0;
//		}
//	}
//	return new MyComparable();
	//方式二:
	return new Comparable(){
		@Override
		public int compareTo(Object o){
			return 0;
		}
	}
	
}
  • 注意点:
  • 在局部内部类的方法中(比如:如果调用局部内部类所声明的方法中的局部变量,要求此局部变量声明为final的)

  • jdk7及之前版本:要求此局部变量显示的声明为final的

  • jdk8及之后的版本:可以省略final的声明

  • 总结:成员内部类和局部内部类,在编译以后,都会生成字节码文件。

3.匿名内部类

public class Test{
	private Runnable runnable = new Runnable(){
		@Override
		public void run(){
		}
	};
}

匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其它类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

二、IO流知识

1. File类的常用方法

  • 获取功能

String getName():获取文件或文件夹的名字
String getPath():获取文件或文件夹的路径
String getParent():获取文件或文件夹的当前路径的上一级路径
String getAbsolutePath():获取文件或文件夹的绝对路径
String[] list():获取指定目录下的所有文件或者文件目录的名称数组
File[] listFiles():获取指定目录下的所有文件或者文件目录的File数组

  • 重命名功能

boolean renameTo(File dest):把文件重命名为指定的文件路径

  • 判断功能

boolean isDirectory():判断是否是目录
boolean isFile():判断是否是文件
boolean isHidden():判断文件是否是隐藏
boolean isAbsolute():判断是否是绝对路径
boolean exists():判断文件或文件夹是否存在
boolean canRead():判断是否可读
boolean canWrite():判断是否可写

  • 创建功能

creatNewFile():若文件存在,则不创建;若文件不存在,则创建
mkdir():若目录存在,则不创建;若目录不存在,则创建单级目录
mkdirs():创建文件目录。如果上层文件目录不存在,一并创建
注意事项:如果你创建文件或者文件目录没有写盘符路径,那么,默认在项目路径下

  • 删除功能

boolean delete():删除文件或者文件夹
void deleteOnExists():退出程序以后才删除
删除注意事项:
Java中的删除不走回收站
要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录

2. IO流的概述

  • 流的分类
  1. 操作数据单位:节点流、字符流
  2. 数据的流向:输入流、输出流
  3. 流的角色:节点流、处理流
    在这里插入图片描述
  • 流的体系结构

在这里插入图片描述
红框对应的是IO流中的4个抽象基类。蓝框常用

  • 重点说明的几个流结构
    在这里插入图片描述
  • 输入、输出的标准化过程
    • 输入过程
      • 创建File对象,指明读取的数据的来源【要求此文件一定要存在
      • 创建对应的输入流,将File类的对象作为参数,传入流的构造器中
      • 具体的读入过程:创建响应的byte[]或char[]
      • 关闭流资源
      • 说明:程序中出现的异常需要使用try-catch-finally处理
    • 输出过程
      • 创建File类对象,指明写出的数据的位置【不要求此文件一定要存在
      • 创建相应的输出流,将File类的对象作为参数,传入流的构造器中
      • 具体的写出过程:write(char[]/byte[] buffer, 0, len)
      • 关闭流资源
      • 说明:程序中出现的异常需要使用try-catch-finally处理

3. FileReader / FileWriter的使用:

  • FileReader的使用

将day09下的hello.txt文件内容读入程序中,并输出到控制台
说明点:

  1. read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
  2. 异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
  3. 读入的文件一定要存在,否则就会报FileNotFoundException。
@Test
    public void testFileReader1()  {
        FileReader fr = null;
        try {
            //1.File类的实例化
            File file = new File("hello.txt");
            //2.FileReader流的实例化
            fr = new FileReader(file);
            //3.读入的操作
            //read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
            char[] cbuf = new char[5];
            int len;
            while((len = fr.read(cbuf)) != -1){
                //方式一:
                //错误的写法
//                for(int i = 0;i < cbuf.length;i++){
//                    System.out.print(cbuf[i]);
//                }
                //正确的写法
//                for(int i = 0;i < len;i++){
//                    System.out.print(cbuf[i]);
//                }
                //方式二:
                //错误的写法,对应着方式一的错误的写法
//                String str = new String(cbuf);
//                System.out.print(str);
                //正确的写法
                String str = new String(cbuf,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fr != null){
                //4.资源的关闭
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  • FileWriter的使用

从内存中写出数据到硬盘的文件里。

说明:
输出操作,对应的File可以不存在的。并不会报异常
File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。
File对应的硬盘中的文件如果存在:
如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原文件的覆盖
如果流使用的构造器是:FileWriter(file,true):不会对原文件覆盖,而是在原文件基础上追加内容

@Test
public void testFileWriter() {
    FileWriter fw = null;
    try {
        //1.提供File类的对象,指明写出到的文件
        File file = new File("hello1.txt");
        //2.提供FileWriter的对象,用于数据的写出
        fw = new FileWriter(file,false);
        //3.写出的操作
        fw.write("I have a dream!\n");
        fw.write("you need to have a dream!");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //4.流资源的关闭
        if(fw != null){
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 文本文件的复制:
@Test
    public void testFileReaderFileWriter() {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            //1.创建File类的对象,指明读入和写出的文件
            File srcFile = new File("hello.txt");
            File destFile = new File("hello2.txt");
            //不能使用字符流来处理图片等字节数据
//            File srcFile = new File("爱情与友情.jpg");
//            File destFile = new File("爱情与友情1.jpg");
            //2.创建输入流和输出流的对象
             fr = new FileReader(srcFile);
            fw = new FileWriter(destFile);
            //3.数据的读入和写出操作
            char[] cbuf = new char[5];
            int len;//记录每次读入到cbuf数组中的字符的个数
            while((len = fr.read(cbuf)) != -1){
                //每次写出len个字符
                fw.write(cbuf,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.关闭流资源
            //方式一:
//            try {
//                if(fw != null)
//                    fw.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }finally{
//                try {
//                    if(fr != null)
//                        fr.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
            //方式二:
            try {
                if(fw != null)
                    fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fr != null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

4 FileInputStream / FileOutputStream的使用:

对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,…),使用字节流处理

/*
实现对图片的复制操作
 */
@Test
public void testFileInputOutputStream()  {
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        //1.造文件
        File srcFile = new File("爱情与友情.jpg");
        File destFile = new File("爱情与友情2.jpg");
        //2.造流
        fis = new FileInputStream(srcFile);
        fos = new FileOutputStream(destFile);
        //3.复制的过程
        byte[] buffer = new byte[5];
        int len;
        while((len = fis.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(fos != null){
            //4.关闭流
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(fis != null){
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

【注意】
相对路径在IDEA和Eclipse中使用的区别?
IDEA:
如果使用单元测试方法,相对路径基于当前的Module的。
如果使用main()测试,相对路径基于当前Project的。
Eclipse:
单元测试方法还是main(),相对路径都是基于当前Project的。

5. 缓冲流

  • 缓冲流涉及到的类:

BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter

  • 作用:

作用:提供流的读取、写入的速度
提高读写速度的原因:内部提供了一个缓冲区。默认情况下是8kb

  • 典型代码
    • 使用BufferedInputStream和BufferedOutputStream:处理非文本文件
//实现文件复制的方法
    public void copyFileWithBuffered(String srcPath,String destPath){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //1.造文件
            File srcFile = new File(srcPath);
            File destFile = new File(destPath);
            //2.造流
            //2.1 造节点流
            FileInputStream fis = new FileInputStream((srcFile));
            FileOutputStream fos = new FileOutputStream(destFile);
            //2.2 造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
            //3.复制的细节:读取、写入
            byte[] buffer = new byte[1024];
            int len;
            while((len = bis.read(buffer)) != -1){
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.资源关闭
            //要求:先关闭外层的流,再关闭内层的流
            if(bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略.
//        fos.close();
//        fis.close();
        }
    }
  • 使用BufferedReader和BufferedWriter:处理文本文件
@Test
    public void testBufferedReaderBufferedWriter(){
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            //创建文件和相应的流
            br = new BufferedReader(new FileReader(new File("dbcp.txt")));
            bw = new BufferedWriter(new FileWriter(new File("dbcp1.txt")));
            //读写操作
            //方式一:使用char[]数组
//            char[] cbuf = new char[1024];
//            int len;
//            while((len = br.read(cbuf)) != -1){
//                bw.write(cbuf,0,len);
//    //            bw.flush();
//            }
            //方式二:使用String
            String data;
            while((data = br.readLine()) != null){
                //方法一:
//                bw.write(data + "\n");//data中不包含换行符
                //方法二:
                bw.write(data);//data中不包含换行符
                bw.newLine();//提供换行的操作
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

6. 转换流的使用

1.转换流涉及到的类:属于字符流
InputStreamReader:将一个字节的输入流转换为字符的输入流
解码:字节、字节数组 —>字符数组、字符串

OutputStreamWriter:将一个字符的输出流转换为字节的输出流
编码:字符数组、字符串 —> 字节、字节数组

说明:编码决定了解码的方式

2.作用:提供字节流与字符流之间的转换

3.图示:
在这里插入图片描述

4.典型实现:

@Test
    public void test1() throws IOException {

        FileInputStream fis = new FileInputStream("dbcp.txt");
//        InputStreamReader isr = new InputStreamReader(fis);//使用系统默认的字符集
        //参数2指明了字符集,具体使用哪个字符集,取决于文件dbcp.txt保存时使用的字符集
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");//使用系统默认的字符集

        char[] cbuf = new char[20];
        int len;
        while((len = isr.read(cbuf)) != -1){
            String str = new String(cbuf,0,len);
            System.out.print(str);
        }

        isr.close();

    }

/*
此时处理异常的话,仍然应该使用try-catch-finally

综合使用InputStreamReader和OutputStreamWriter
 */
@Test
public void test2() throws Exception {
    //1.造文件、造流
    File file1 = new File("dbcp.txt");
    File file2 = new File("dbcp_gbk.txt");

    FileInputStream fis = new FileInputStream(file1);
    FileOutputStream fos = new FileOutputStream(file2);

    InputStreamReader isr = new InputStreamReader(fis,"utf-8");
    OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");

    //2.读写过程
    char[] cbuf = new char[20];
    int len;
    while((len = isr.read(cbuf)) != -1){
        osw.write(cbuf,0,len);
    }

    //3.关闭资源
    isr.close();
    osw.close();
}

5.说明:
//文件编码的方式(比如:GBK),决定了解析时使用的字符集(也只能是GBK)。

7. 其它流的使用

7.1标准的输入输出流:

System.in:标准的输入流,默认从键盘输入
System.out:标准的输出流,默认从控制台输出

修改默认的输入和输出行为:
System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入和输出的流。

7.2打印流

PrintStream 和PrintWriter
说明:
提供了一系列重载的print()和println()方法,用于多种数据类型的输出
System.out返回的是PrintStream的实例

7.3数据流:

DataInputStream 和 DataOutputStream
作用:
用于读取或写出基本数据类型的变量或字符串

示例代码:

/*
练习:将内存中的字符串、基本数据类型的变量写出到文件中。

注意:处理异常的话,仍然应该使用try-catch-finally.
 */
@Test
public void test3() throws IOException {
    //1.
    DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
    //2.
    dos.writeUTF("刘建辰");
    dos.flush();//刷新操作,将内存中的数据写入文件
    dos.writeInt(23);
    dos.flush();
    dos.writeBoolean(true);
    dos.flush();
    //3.
    dos.close();

}
/*
将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中。

注意点:读取不同类型的数据的顺序要与当初写入文件时,保存的数据的顺序一致!

 */
@Test
public void test4() throws IOException {
    //1.
    DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
    //2.
    String name = dis.readUTF();
    int age = dis.readInt();
    boolean isMale = dis.readBoolean();
System.out.println("name = " + name);
System.out.println("age = " + age);
System.out.println("isMale = " + isMale);

//3.
dis.close();
}

三、常用类

1. String、StringBuffer、StringBuilder类

1 String、StringBuffer、StringBuilder三者的对比

String:不可变的字符序列;底层使用char[]存储

StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[]存储

StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储

2 StringBuffer与StringBUilder的内存解析

以StringBuffer为例:

String str = new String();//char[] value = new char[0];
String str1 = new String("abc");//char[] value = new char[] {'a','b','c'};

StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底层创建了一个长度是16的数组
System.out.println(sb1.length());//0
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';

StringBuffer sb1 = new StringBuffer("abc");char[] value = new char["abc".length()+16];

//问题1:System.out.println(sb2.length());//3
//问题2:扩容问题:如果要添加的数据底层数组盛不下了,就需要扩容底层的数组。默认情况下,扩容为原来容量的2倍+2,同时将原数组中的元素复制到新的数组中
//开发中建议使用StringBuffer(int capacity)或StringBuilder(int capacity)

3 对比String、StringBuffer、StringBuilder三者的执行效率

从高到底排列:StringBuilder > StringBuffer > String

4 StringBuffer、StringBuilder中的常用方法

  • 增:append(xxx)

  • 删:delete(int start,int end)

  • 改:setCharAt(int n, char ch) / replace(int start, int end, String str)

  • 查charAt(int n )

  • 插:insert(int offset, xxx)

  • 长度:length()

  • 遍历:for() + charAt() / toString()

2. 枚举类(enum)

1. 枚举类的说明:

  • 枚举类的理解:类的对象只有有限个,确定的。我们称此类为枚举类
  • 当需要定义一组常量时,强烈建议使用枚举类
  • 如果枚举类中只有一个对象,则可以作为单例模式的实现方式。

2. 如何自定义枚举类?步骤:

//自定义枚举类
class Season{
    //1.声明Season对象的属性:private final修饰
    private final String seasonName;
    private final String seasonDesc;

    //2.私有化类的构造器,并给对象属性赋值
    private Season(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //3.提供当前枚举类的多个对象:public static final的
    public static final Season SPRING = new Season("春天","春暖花开");
    public static final Season SUMMER = new Season("夏天","夏日炎炎");
    public static final Season AUTUMN = new Season("秋天","秋高气爽");
    public static final Season WINTER = new Season("冬天","冰天雪地");

    //4.其他诉求1:获取枚举类对象的属性
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }
    //4.其他诉求1:提供toString()
    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}

3. jdk 5.0 新增使用enum定义枚举类。步骤:

enum Season1 {
    //1.提供当前枚举类的对象,多个对象之间用","隔开,末尾对象";"结束
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","冰天雪地");

    //2.声明Season对象的属性:private final修饰
    private final String seasonName;
    private final String seasonDesc;

    //2.私化类的构造器,并给对象属性赋值

    private Season1(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //4.其他诉求1:获取枚举类对象的属性
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

}

4. 使用enum定义枚举类之后,枚举类常用方法:(继承于java.lang.Enum类)

Season1 summer = Season1.SUMMER;
        //toString():返回枚举类对象的名称
        System.out.println(summer.toString());

//        System.out.println(Season1.class.getSuperclass());
        System.out.println("****************");
        //values():返回所的枚举类对象构成的数组
        Season1[] values = Season1.values();
        for(int i = 0;i < values.length;i++){
            System.out.println(values[i]);
        }
        System.out.println("****************");
        Thread.State[] values1 = Thread.State.values();
        for (int i = 0; i < values1.length; i++) {
            System.out.println(values1[i]);
        }

        //valueOf(String objName):返回枚举类中对象名是objName的对象。
        Season1 winter = Season1.valueOf("WINTER");
        //如果没objName的枚举类对象,则抛异常:IllegalArgumentException
//        Season1 winter = Season1.valueOf("WINTER1");
        System.out.println(winter);

5. 使用enum定义枚举类之后,如何让枚举类对象分别实现接口:

interface Info{
    void show();
}

//使用enum关键字枚举类
enum Season1 implements Info{
    //1.提供当前枚举类的对象,多个对象之间用","隔开,末尾对象";"结束
    SPRING("春天","春暖花开"){
        @Override
        public void show() {
            System.out.println("春天在哪里?");
        }
    },
    SUMMER("夏天","夏日炎炎"){
        @Override
        public void show() {
            System.out.println("宁夏");
        }
    },
    AUTUMN("秋天","秋高气爽"){
        @Override
        public void show() {
            System.out.println("秋天不回来");
        }
    },
    WINTER("冬天","冰天雪地"){
        @Override
        public void show() {
            System.out.println("大约在冬季");
        }
    };
}

3. 包装类

4. Math类

  • java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double型。
方法:
绝对值:Math.abs(-98)
求两个数的最大值:Math.max(34, 56)
求三个数最大值:Math.max(32, Math.max(56,12))
最小值:Math.min(12, 34)
向上取整:Math.ceil(32.1)
向下取整:Math.floor(31.2)
四舍五入:Math.round(56.72)
随机数:Math.random()

5. Random类

public class Demo1 {
    public static void main(String[] args) {
        Random random = new Random();
        System.out.println(random.nextInt());
        System.out.println(random.nextBoolean());
        System.out.println(random.nextDouble());
        System.out.println(random.nextFloat());
        System.out.println(random.nextLong());
    }
}

6. System类

System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。
由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实例化该类。其内部的成员变量和成员方法都是static的,所以也可以很方便的进行调用。

方法:
native long currentTimeMillis()
void exit(int status)
void gc()
String getProperty(String key)

7. Runtime类

public class Demo1 {
    public static void main(String[] args) throws IOException {
        Runtime runtime = Runtime.getRuntime();
        //返回Java虚拟机将尝试使用的最大内存量。
        System.out.println(runtime.maxMemory() / 1024 / 1024);
        //返回Java虚拟机中的可用内存量
        System.out.println(runtime.freeMemory()/1024/1024);
        //返回Java虚拟机中的内存总量
        System.out.println(runtime.totalMemory()/1024/1024);

        //public Process exec(String command)
        //             throws IOException
        //在单独的进程中执行指定的字符串命令。
        //这是一种方便的方法。 调用表单exec(command)的行为方式与调用exec(command, null, null)完全相同 。
        runtime.exec("C:\\Program Files (x86)\\Nwt\\ShiYeLine.exe");
    }
}

8. JDK 8 之前的日期时间API

1.获取系统当前时间:System类中的currentTimeMillis()

long time = System.currentTimeMillis();
//返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
//称为时间戳
System.out.println(time);

2. java.util.Date类与java.sql.Date类

java.util.Date|---java.sql.Date1.两个构造器的使用
    构造器一:Date():创建一个对应当前时间的Date对象
    构造器二:创建指定毫秒数的Date对象
2.两个方法的使用
    toString():显示当前的年、月、日、时、分、秒
    getTime():获取当前Date对象对应的毫秒数。(时间戳)

3. java.sql.Date对应着数据库中的日期类型的变量
    如何实例化?
    如何将java.util.Date对象转换为java.sql.Date对象?
 @Test
 public void test2(){
//构造器一:Date():创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1.toString());//Sat Feb 16 16:35:31 GMT+08:00 2019

System.out.println(date1.getTime());//1550306204104

//构造器二:创建指定毫秒数的Date对象
Date date2 = new Date(155030620410L);
System.out.println(date2.toString());

//创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(35235325345L);
System.out.println(date3);//1971-02-13

//如何将java.util.Date对象转换为java.sql.Date对象
//情况一:
//        Date date4 = new java.sql.Date(2343243242323L);
//        java.sql.Date date5 = (java.sql.Date) date4;
//情况二:
Date date6 = new Date();
java.sql.Date date7 = new java.sql.Date(date6.getTime());
}

3. java.text.SimpleDataFormat类

SimpleDateFormat对日期Date类的格式化和解析
1.两个操作:
1.1 格式化:日期 --->字符串
1.2 解析:格式化的逆过程,字符串 ---> 日期

2.SimpleDateFormat的实例化:new + 构造器

//*************按照指定的方式格式化和解析:调用带参的构造器*****************
//        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm aaa");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        //格式化
        String format1 = sdf1.format(date);
        System.out.println(format1);//2019-02-18 11:48:27
        //解析:要求字符串必须是符合SimpleDateFormat识别的格式(通过构造器参数体现),
        //否则,抛异常
        Date date2 = sdf1.parse("2020-02-18 11:48:27");
        System.out.println(date2);

小练习:
/*
    练习一:字符串"2020-09-08"转换为java.sql.Date
练习二:"三天打渔两天晒网"   1990-01-01  xxxx-xx-xx 打渔?晒网?

举例:2020-09-08 ? 总天数

总天数 % 5 == 1,2,3 : 打渔
总天数 % 5 == 4,0 : 晒网

总天数的计算?
方式一:( date2.getTime() - date1.getTime()) / (1000 * 60 * 60 * 24) + 1
方式二:1990-01-01  --> 2019-12-31  +  2020-01-01 -->2020-09-08
 */
@Test
public void testExer() throws ParseException {
    String birth = "2020-09-08";

    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
    Date date = sdf1.parse(birth);
    //  System.out.println(date);
        java.sql.Date birthDate = new java.sql.Date(date.getTime());
    System.out.println(birthDate);
}

4. Calendar类:日历类、抽象类

   //1.实例化
   //方式一:创建其子类(GregorianCalendar的对象
   //方式二:调用其静态方法getInstance()
    Calendar calendar = Calendar.getInstance();
//        System.out.println(calendar.getClass());
   //2.常用方法
    //get()
    int days = calendar.get(Calendar.DAY_OF_MONTH);
    System.out.println(days);
    System.out.println(calendar.get(Calendar.DAY_OF_YEAR));

    //set()
    //calendar可变性
     calendar.set(Calendar.DAY_OF_MONTH,22);
    days = calendar.get(Calendar.DAY_OF_MONTH);
    System.out.println(days);

    //add()
    calendar.add(Calendar.DAY_OF_MONTH,-3);
    days = calendar.get(Calendar.DAY_OF_MONTH);
    System.out.println(days);

    //getTime():日历类---> Date
    Date date = calendar.getTime();
    System.out.println(date);

    //setTime():Date ---> 日历类
    Date date1 = new Date();
    calendar.setTime(date1);
    days = calendar.get(Calendar.DAY_OF_MONTH);
    System.out.println(days);

9. JDK 8 之前的日期时间API

1.日期时间API的迭代:

第一代:jdk 1.0 Date类
第二代:jdk 1.1 Calendar类,一定程度上替换Date类
第三代:jdk 1.8 提出了新的一套API

2.前两代存在的问题举例:

可变性:像日期和时间这样的类应该是不可变的。
偏移性:Date中的年份是从1900开始的,而月份都从0开始。
格式化:格式化只对Date用,Calendar则不行。
此外,它们也不是线程安全的;不能处理闰秒等。

3.java 8 中新的日期时间API涉及到的包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NoDtAqHQ-1663417121302)(C:\Users\92164\AppData\Roaming\Typora\typora-user-images\image-20220917200443003.png)]

4.本地日期、本地时间、本地日期时间的使用:LocalDate / LocalTime / LocalDateTime

4.1 说明:

① 分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。
② LocalDateTime相较于LocalDate、LocalTime,使用频率要高
③ 类似于Calendar

4.2 常用方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zuRbFWaC-1663417121303)(C:\Users\92164\AppData\Roaming\Typora\typora-user-images\image-20220917200610105.png)]

5.时间点:Instant

5.1 说明:

① 时间线上的一个瞬时点。 概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC开始的秒数。)
② 类似于 java.util.Date类

5.2 常用方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S88MvZin-1663417121304)(C:\Users\92164\AppData\Roaming\Typora\typora-user-images\image-20220917200651101.png)]

6.日期时间格式化类:DateTimeFormatter

6.1 说明:

① 格式化或解析日期、时间
② 类似于SimpleDateFormat

6.2 常用方法:

① 实例化方式:
预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)

② 常用方法:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-on04KrsX-1663417121304)(C:\Users\92164\AppData\Roaming\Typora\typora-user-images\image-20220917200730375.png)

特别的:自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
//  重点:自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");

//格式化
String str4 = formatter3.format(LocalDateTime.now());
System.out.println(str4);//2019-02-18 03:52:09

//解析
TemporalAccessor accessor = formatter3.parse("2019-02-18 03:52:09");
System.out.println(accessor);

7.其它API的使用 (不讲)

7.1 带时区的日期时间:ZonedDateTime / ZoneId
举例:
// ZoneId:类中包含了所的时区信息
	@Test
	public void test1(){
		//getAvailableZoneIds():获取所的ZoneId
		Set<String> zoneIds = ZoneId.getAvailableZoneIds();
		for(String s : zoneIds){
			System.out.println(s);
		}
		System.out.println();
		//获取“Asia/Tokyo”时区对应的时间
	LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
	System.out.println(localDateTime);
}
//ZonedDateTime:带时区的日期时间
	@Test
	public void test2(){
		//now():获取本时区的ZonedDateTime对象
		ZonedDateTime zonedDateTime = ZonedDateTime.now();
		System.out.println(zonedDateTime);
		//now(ZoneId id):获取指定时区的ZonedDateTime对象
		ZonedDateTime zonedDateTime1 = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
		System.out.println(zonedDateTime1);
	}
7.2 时间间隔:Duration–用于计算两个“时间”间隔,以秒和纳秒为基准

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9dKK7mM8-1663417121305)(C:\Users\92164\AppData\Roaming\Typora\typora-user-images\image-20220917200911350.png)]

举例:

@Test
	public void test3(){
		LocalTime localTime = LocalTime.now();
		LocalTime localTime1 = LocalTime.of(15, 23, 32);
		//between():静态方法,返回Duration对象,表示两个时间的间隔
		Duration duration = Duration.between(localTime1, localTime);
		System.out.println(duration);
		System.out.println(duration.getSeconds());
	System.out.println(duration.getNano());
	
	LocalDateTime localDateTime = LocalDateTime.of(2016, 6, 12, 15, 23, 32);
	LocalDateTime localDateTime1 = LocalDateTime.of(2017, 6, 12, 15, 23, 32);
	
	Duration duration1 = Duration.between(localDateTime1, localDateTime);
	System.out.println(duration1.toDays());
}	
7.3 日期间隔:Period --用于计算两个“日期”间隔,以年、月、日衡量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GptDXMaj-1663417121306)(C:\Users\92164\AppData\Roaming\Typora\typora-user-images\image-20220917200953142.png)]

举例:
	@Test
	public void test4(){
		LocalDate localDate = LocalDate.now();
		LocalDate localDate1 = LocalDate.of(2028, 3, 18);
		
		Period period = Period.between(localDate, localDate1);
		System.out.println(period);
		
		System.out.println(period.getYears());
		System.out.println(period.getMonths());
		System.out.println(period.getDays());
		
		Period period1 = period.withYears(2);
		System.out.println(period1);
	}
7.4 日期时间校正器:TemporalAdjuster
举例:
	@Test
	public void test5(){
		//获取当前日期的下一个周日是哪天?
		TemporalAdjuster temporalAdjuster = TemporalAdjusters.next(DayOfWeek.SUNDAY);
		
		LocalDateTime localDateTime = LocalDateTime.now().with(temporalAdjuster);
		System.out.println(localDateTime);
	
		//获取下一个工作日是哪天?
		LocalDate localDate = LocalDate.now().with(new TemporalAdjuster(){
			@Override
			public Temporal adjustInto(Temporal temporal) {
				LocalDate date = (LocalDate)temporal;
				if(date.getDayOfWeek().equals(DayOfWeek.FRIDAY)){
					return date.plusDays(3);
				}else if(date.getDayOfWeek().equals(DayOfWeek.SATURDAY)){
					return date.plusDays(2);
				}else{
					return date.plusDays(1);
				}	
			}
		});
		System.out.println("下一个工作日是:" + localDate);
	}

10. BigInteger类、BigDecimal类

说明:
① java.math包的BigInteger可以表示不可变的任意精度的整数。
② 要求数字精度比较高,用到java.math.BigDecimal类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8iV9dJlS-1663417121306)(C:\Users\92164\AppData\Roaming\Typora\typora-user-images\image-20220917201653820.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值