Java基础入门14:常用API(Object(s)类、包装类、Math、Arrays、日期时间、Lambda表达式、方法引用)

Object类

Object类是Java中所有类的祖宗类,因此,Java中所有类的对象都可以直接使用Object类中提供的一些方法。

Object类的常见方法:

package com.itchinajie.d12_api_object;

public class Test {
    public static void main(String[] args) {
        //目标:掌握Object类提供的常用方法
        Student s1 = new Student("张三",18);
        //System.out.println(s1.toString());可省略.toString()
        System.out.println(s1);
        Student s2 = new Student("张三",18);
        System.out.println(s2.equals(s1));//false比较的地址,重写之后可以自定义比较规则
        System.out.println(s2 == s1);
    }
}




package com.itchinajie.d12_api_object;

import java.util.Objects;

public class Student {//会默认继承extends Object{
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    //重写equals方法,比较两个对象的内容是否一样
    //比较者:s2 == this
    //被比较者:s1 == 0
    @Override
    public boolean equals(Object o) {
        //1、判断两个对象是否地址一样,一样直接返回true
        if (this == o) return true;
        //2、判断o是null直接返回false,或者比较者的类型与被比较者的类型不一样,返回false
        if (o == null || getClass() != o.getClass()) return false;
        //3、o不是null,且o一定是学生类型的对象,开始比较内容了
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

toString存在的意义:toString()方法存在的意义就是为了被子类重写,以便返回对象具体的内容。
equals存在的意义:直接比较两个对象的地址是否相同完全可以用"==”替代equals,equals存在的意义
就是为了被子类重写,以便子类自己来定制比较规则(比如比较对象内容)。

Object提供的对象克隆方法

当某个对象调用这个方法时,这个方法会复制一个一模一样的新对象返回。

深克隆:

对象中基本类型的数据直接拷贝
对象中的字符串数据拷贝的还是地址
对象中还包含的其他对象,不会拷贝地址,会创建新对象。

浅克隆

拷贝出的新对象,与原对象中的数据一模一样(引用类型拷贝的只是地址)

package com.itchinajie.d12_api_object;

public class Test2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        //目标:掌握Object类提供的对象克隆的方法
        //1、protaected Object clone();对象克隆
        User u1 = new User(10,"你好","666",new double[]{23,24,35});

        System.out.println(u1.getId());
        System.out.println(u1.getPassword());
        System.out.println(u1.getUsername());
        System.out.println(u1.getScores());

        User u2 = (User)u1.clone();
        System.out.println(u2.getId());
        System.out.println(u2.getPassword());
        System.out.println(u2.getUsername());
        System.out.println(u2.getScores());
    }
}



package com.itchinajie.d12_api_object;
//Cloneable是一个表接口
//规则
public class User implements Cloneable{
    private int id;//编号
    private String username;//用户名
    private String password;//密码
    private double[] scores;//分数

    public User() {
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //super去调用父类Object中的clone方法
        User u2 = (User) super.clone();
        u2.scores = u2.scores.clone();
        return super.clone();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public double[] getScores() {
        return scores;
    }

    public void setScores(double[] scores) {
        this.scores = scores;
    }

    public User(int id, String username, String password, double[] scores) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.scores = scores;
    }
}

Objects类

Objects是一个工具类,提供了很多操作对象的静态方法给我们使用。

包装类

包装类就是把基本类型的数据包装成对象。

自动装箱:基本数据类型可以自动转换为包装类型。

自动拆箱:包装类型可以自动转换为基本数据类型。

package com.itchinajie.d14_integer;

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        //目标:掌握包装类的使用
        //Integer a1 = new Integer(12);已过时
        Integer a2 = Integer.valueOf(12);
        System.out.println(a2);

        //自动拆箱:可以把基本类型的数据转换成对象
        int a3 = 12;

        //自动拆箱:可以自动把包装类型的对象转换成对应的基本数据类型
        int a4 = a3;

        //泛型和集合不支持基本数据类型,只能支持使用引用数据类型
        //ArrayList<int> list = new ArrayList<>();
        ArrayList<Integer> list = new ArrayList<>();
        list.add(12);
        list.add(13);

        int rs = list.get(1);//自动拆箱
        System.out.println("---------------------");
        //1、把基本数据类型换成字符串
        Integer a = 23;
        String rs1 = Integer.toString(a);//"23"
        System.out.println(rs1 + 1);//231

        String rs2 = a.toString();//"23"
        System.out.println(rs2 + 1);//231

        String rs3 = a + "";
        System.out.println(rs3 + 1);

        //2、把字符串类型的数值转换成对应的基本类型
        String agestr = "29";
        //int ageI = Interger.parseInt(ageStr);//29
        int ageI = Integer.valueOf(agestr);//29
        System.out.println(ageI + 1);//30

        String scoreStr = "99.5";
        //double score = Double.parseDouble(scoreStr);//99.5
        double score = Double.valueOf(scoreStr);//99.5
        System.out.println(score +0.5);

    }
}

包装类的其他常见操作

可以把基本类型的数据转换成字符串类型。

可以把字符类型的数值转换成字符本身对应的数据类型。

StringBuilder、StringBuffer

StringBuilder

StringBuilder代表可变字符串对象,相当于是一个容器,它里面装的字符串是可以改变的,就是用来操作字符串的。
好处:StringBuilder比String更适合做字符串的修改操作,效率会更高,代码也会更简洁。

package com.itchinajie.d15_stringBuilder;

public class Test1 {
    public static void main(String[] args) {
        //目标:搞清楚StringBuilder的用法和作用
        //StringBuilder s = new StringBuilder();//s""
        StringBuilder s = new StringBuilder("itchinajie");

        //1、拼接内容
        s.append("黑马");
        s.append(12);
        s.append(true);

        //支持链式编程
        s.append(666).append("黑马2").append(666);
        System.out.println(s);

        //反转操作
        s.reverse();
        System.out.println(s);

        //3、返回字符串的长度
        System.out.println(s.length());

        //把StringBuilder对象又转换成String类型
        String rs = s.toString();
        System.out.println(rs);

    }
}

为啥操作字符串建议使用StringBuilder,而不用原来学过的String?

对于字符串相关的操作,如频繁的拼接、修改等,建议用StringBuidler,效率更高!
注意:如果操作字符串较少,或者不需要操作,以及定义字符串变量,还是建议用String。

StringBuffer:

StringBuffer的用法与StringBuilder是一模一样的但StringBuilder是线程不安全的StringBuffer是线程安全的。

StringJonier

JDK8开始才有的,跟StringBuilder-一样,也是用来操作字符串的,也可以看成是一个容器,创建之后里面的内容是可变的。

好处:不仅能提高字符串的操作效率,并且在有些场景下使用它操作字符串,代码会更简洁。

既能高效,又能实现更方便的拼接。

package com.itchinajie.d16_stringjoiner;

import java.util.StringJoiner;

public class Test {
    public static void main(String[] args) {
        //目标:掌握StringJoiner的用法
        StringJoiner s = new StringJoiner(",","[","]");//间隔符
        s.add("Java1");
        s.add("Java2");
        s.add("Java3");

        System.out.println(s);

        System.out.println(getArrayData(new int[]{11, 22, 33, 44, 55, 66, 77, 88, 99, 0}));
    }
    public static String getArrayData(int[] arr){
        //1、判断arr书否为null
        if(arr == null){
            return null;
        }

        //arr数组对象存在。
        StringJoiner s = new StringJoiner(",","[","]");
        for (int i = 0; i < arr.length; i++) {
            s.add(arr[i] + "");
        }
        return s.toString();
    }
}

Math类

代表数学,是一个工具类,里面提供的都是对数据进行操作的一些静态方法。

package com.itchinajie.d1_math;

public class MathTest {
    public static void main(String[] args) {
        //目标:了解一下Math类提供的常见方法
        //1、public static int abs(int a):取绝对值(拿到的结果一定是正数)
        // public static double abs(double a)
        System.out.println(Math.abs(-12));
        System.out.println(Math.abs(123));
        System.out.println(Math.abs(-3.14));


        //2、public static double cei(double a):向上取整
        System.out.println(Math.ceil(4.000001));//5.0
        System.out.println(Math.ceil(4.0));//4.0

        //3、public static double floor(double a):向下取整
        System.out.println(Math.floor(4.999999));//4.0
        System.out.println(Math.floor(4.0));//4.0

        //4、public static long round(double a):四舍五入
        System.out.println(Math.round(3.49999));//3
        System.out.println(Math.round(3.500001));//4

        //5、public static int max(int a,int b):取较大值
        //   public static int max(int a,int b):取较小值
        System.out.println(Math.max(10, 20));
        System.out.println(Math.min(10, 20));

        //6、public static double pow(double a,double b):取次方
        System.out.println(Math.pow(2, 3));
        System.out.println(Math.pow(3,2));
        //7、public static double random():取随机数 [0.0,1.0)(包前不包后)
        System.out.println(Math.random());
    }
}

System类

System代表程序所在的系统,也是一个工具类。

package com.itchinajie.d1_math;

public class SystemTest {
    public static void main(String[] args) {
        //目标:了解System类的常见方法
        //1、public static void exit(int status);
        //  终止当前运行的Java虚拟机
        //  该参数用状态代码;按照惯例,非零状态代码表示异常终止


        //2、public static long currenTimeMillis();
        //  取当前系统的时间
        //  返回的是long类型的时间毫秒值,值得是从1970-1-1 0:0:0 开始走到此刻的总的毫秒值,1s ==1000ms
        long time = System.currentTimeMillis();
        System.out.println(time);

        for (int i = 0; i < 1000000; i++) {
            System.out.println("输出了:" + i);
        }

        long time2 = System.currentTimeMillis();
        System.out.println((time2 - time) / 1000.0 + "s");
    }
}

时间毫秒值:指的是从1970年1月1日   00:00:00走到此刻的总的毫秒数,应该是很大的,1s=1000ms.

为啥选择“1970年1月1日00:00:00”作为时间的起点?

1969年8月,贝尔实验室的程序员肯汤普逊利用妻儿离开一个月的机会,开始着手创造一个全新的革命性的操作系统,他使用B编译语言在老旧的PDP-7机器上开发出了UNix的一个版本。随后,汤普逊和同事丹尼斯里奇改进了B语言,开发出了C语言,重写了UNiX.1970年1月1日算C语言的生日。

RunTime类

代表程序所在的运行环境。

Runtime类是个单例类。

BigDecimal

JDK8之前传统的日期、时间

Date

代表的是日期和时间。

package com.itchinajie.d2_time;

import java.util.Date;

public class Test1Date {
    public static void main(String[] args) {
        //目标:掌握Date日期类的使用
        //1、创建一个Date的对象,代表系统当前时间信息的
        Date d = new Date();
        System.out.println(d);

        //2、拿到时间毫秒值
        long time = d.getTime();
        System.out.println(time);

        //3、把时间毫秒值转换成日期对象:2s之后的时间是多少
        time += 2*1000;
        Date d2 = new Date(time);
        System.out.println(d2);

        //4、直接把日期对象的时间通过setTime方法进行修改
        Date d3 = new Date();
        d3.setTime(time);
        System.out.println(d3);


    }
}

SimpleDateFormat

代表简单日期格式化,可以用来把日期对象、时间毫秒值格式化成我们想要的形式。

package com.itchinajie.d2_time;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Test2SimpleDateFormat {
    public static void main(String[] args) throws ParseException {
        //目标:掌握SimpleDateFormat的使用
        //1、准备一些时间
        Date d = new Date();
        System.out.println(d);

        long time = d.getTime();
        System.out.println(time);

        //2、格式化日期对象,和时间  毫秒值
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss  EEE  a");

        String rs = sdf.format(d);
        String rs2 = sdf.format(time);
        System.out.println(rs);
        System.out.println(rs2);
        System.out.println("----------------------------------");

        //目标:掌握SimpleDateFormat解析字符串时间,成为日期对象
        String dateSr = "2022-12-12  12:12:11";
        //1、创建简单日期格式化对象,指定的时间格式必须与被解析的时间格式一模一样,否则程序会出bug
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
        Date d2 = sdf2.parse(dateSr);

        System.out.println(d2);


    }
}

时间格式的常见符号:

SimpleDateFormat解析字符串时间成为日期对象

秒杀活动案例

需求
小贾下单并付款的时间为:2023年11月11日0:01:18
小皮下单并付款的时间为:2023年11月11日0:10:51
请用代码说明这两位同学有没有参加上秒杀活动?

package com.itchinajie.d2_time;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Test3 {
    public static void main(String[] args) throws ParseException {
        //目标:完成秒杀案例
        //1、把时间开始、结束时间、小贾下单时间、小皮下单时间拿到程序中
        String start = "2023年11月11日 0:0:0";
        String end = "2023年11月11日 0:10:0";
        String xj = "2023年11月11日 0:01:18";
        String xp = "2023年11月11日 0:10:57";

        //2、把字符串的时间解析成日期对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Date startDt = sdf.parse(start);
        Date endDt = sdf.parse(end);
        Date xjDt = sdf.parse(xj);
        Date xpDt = sdf.parse(xp);

        //3、开始判断小皮和小贾是否秒杀成功
        //把日期对象换成时间毫秒值来判断
        long startTime = startDt.getTime();
        long endTime = endDt.getTime();
        long xjTime = xjDt.getTime();
        long xpTime = xpDt.getTime();

        if (xjTime >= startTime && xjTime <= endTime) {
            System.out.println("小贾您秒杀成功了~~");
        }else{
            System.out.println("小贾您秒杀失败了~~");
        }

        if (xpTime >= startTime && xpTime <= endTime) {
            System.out.println("小皮您秒杀成功了~~");
        }else{
            System.out.println("小皮您秒杀失败了~~");
        }
    }

}

calendar

代表的是系统此刻时间对应的日历。
通过它可以单独获取、修改时间中的年、月、日、时、分、秒等。

package com.itchinajie.d2_time;

import java.util.Calendar;
import java.util.Date;

public class Test4Calendar {
    public static void main(String[] args) {
        //目标:掌握Calendar的使用和特点
        //1、得到系统此刻的时间对应的日历对象
        Calendar now = Calendar.getInstance();
        System.out.println(now);

        //2、获取日历中的某个信息
        int year = now.get(Calendar.YEAR);
        System.out.println(year);

        int days = now.get(Calendar.DAY_OF_YEAR);
        System.out.println(days);

        //3、拿到日历中记录的日期对象
        Date d = now.getTime();
        System.out.println(d);

        //4、拿到时间毫秒值
        long time = now.getTimeInMillis();
        System.out.println(time);

        //5、修改日历中的某个信息
        now.set(Calendar.MONTH,9);//修改月份成10月份
        now.set(Calendar.DAY_OF_YEAR,125);//修改成一年中的第125天
        System.out.println(now);

        //6、为某个信息增加或者减少多少
        now.add(Calendar.DAY_OF_YEAR,100);
        now.add(Calendar.DAY_OF_YEAR,-10);
        now.add(Calendar.DAY_OF_MONTH,6);
        now.add(Calendar.HOUR,12);
        System.out.println(now);

    }
}

注意:calendar是可变对象,一旦修改后其对象本身表示的时间将产生变化。

JDK8之前新增的日期、时间

代替calendar

LocalDate的常用API(都是处理年、月、日、星期相关的)。

package com.itchinajie.d4_jdk8_time;

import java.time.LocalDate;

public class Test1_LocalDate {
    public static void main(String[] args) {
        //0、获取本地日期的对象
        LocalDate ld = LocalDate.now();//年 月 日
        System.out.println(ld);

        //1、获取日期对象中的信息
        int year = ld.getYear();//年
        int month = ld.getMonthValue();//月 (1-12)
        int day = ld.getDayOfMonth();//日
        int dayOfYear = ld.getDayOfYear();//一年中的第几天
        int dayOfWeek = ld.getDayOfWeek().getValue();//星期几
        System.out.println(year);
        System.out.println(day);
        System.out.println(dayOfWeek);

        //2、直接修改某个信息:withYear、withMonth、withWeek、withDay
        LocalDate ld2 = ld.withYear(2099);
        LocalDate ld3 = ld.withMonth(12);
        System.out.println(ld2);
        System.out.println(ld3);
        System.out.println(ld);

        //3、把某个信息加多少:plusYears、plusMonths、plusDays、plusWeeks
        LocalDate ld4 = ld.plusYears(2099);
        LocalDate ld5 = ld.plusMonths(12);
        System.out.println(ld4);
        System.out.println(ld5);

        //4、打某个对象信息减少:minusYears、minusMonths、minusDays、minusWeeks
        LocalDate ld6 = ld.minusYears(2099);
        LocalDate ld7 = ld.minusMonths(12);
        System.out.println(ld6);
        System.out.println(ld7);

        //5、获取指定日期的LocalDate的对象:public static LocalDate of(int year,int month ,int dayOfMonth)
        LocalDate ld8 = LocalDate.of(2099,12,12);
        LocalDate ld9 = LocalDate.of(2099,12,12);
        System.out.println(ld8);
        System.out.println(ld9);

        //6、判断2个日期对象是否相等,在前还是在后:equals isBefore isAfter
        System.out.println(ld8.equals(ld9));//true
        System.out.println(ld8.isAfter(ld));//true
        System.out.println(ld8.isBefore(ld));//true

    }
}

LocalDateTime的常用API(可以处理年、月、日、星期、时、分、秒、纳秒等信息)

package com.itchinajie.d4_jdk8_time;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Test3_LocalDateTime {
    public static void main(String[] args) {
        //0、获取本地日期和时间对象。
        LocalDateTime ldt=LocalDateTime.now();//年 月 日 时 分 秒 纳秒
        System.out.println(ldt);

        //1、可以获取日期和时间的全部信息
        int year = ldt.getYear();//年
        int month = ldt.getMonthValue();//月
        int day = ldt.getDayOfMonth();//日
        int day0fYear = ldt.getDayOfYear();//一年中的第几天
        int day0fWeek = ldt.getDayOfWeek().getValue();//获取是周几
        int hour = ldt.getHour();//时
        int minute = ldt.getMinute();//分
        int second = ldt.getSecond();//秒
        int nano = ldt.getNano();//纳秒
        //12、修改时间信息:
        //withYear withMonth withDayOfMonth withDayOfYear withHour withMinute withSecond withNano
        LocalDateTime ldt2 = ldt.withYear(2029);
        LocalDateTime ldt3 = ldt.withMinute(59);
        //3、加多少:
        //plusYears plusMonths plusDays plusWeeks plusHours plusMinutes plusSeconds plusNanos
        LocalDateTime ldt4 = ldt.plusYears(2);
        LocalDateTime ldt5 = ldt.plusMinutes(3);
        //4、减多少:
        //minusDays minusYears minusMonths minusWeeks minusHours minusMinutes minusSeconds minusNar
        LocalDateTime ldt6 = ldt.minusYears(2);
        LocalDateTime ldt7 = ldt.minusMinutes(3);
        //5、获取指定日期和时间的LocalDateTime对象:
        //public static LocalDateTime of(int year,Month month,int dayOfMonth,int hour,
        //                                  int minute,int second,int nanoOfSecond)
        LocalDateTime ldt8 = LocalDateTime.of(2029,12,12,12,12,12,12);
        LocalDateTime ldt9 = LocalDateTime.of(2029,12,12,12,12,12,12);
        //6、判断2个日期、时间对象,是否相等,在前还是在后:equals、isBefore、isAfter
        System.out.println(ldt9.equals(ldt8));
        System.out.println(ldt9.isAfter(ldt));
        System.out.println(ldt9.isBefore(ldt));

        //7、可以把LocalDateTime.转换成LocalDate和LocalTime
        //public LocalDate toLocalDate()
        //public LocalTime toLocalTime()
        //public static LocalDateTime of(LocalDate date,LocalTime time)
        LocalDate ld = ldt.toLocalDate();
        LocalTime lt = ldt.toLocalTime();
        LocalDateTime ldt10 = LocalDateTime.of(ld,lt);
    }
}

LocalTime的常用API(都是处理时、分、秒、纳秒相关的)。

package com.itchinajie.d4_jdk8_time;

import java.time.LocalTime;

public class Test2_LocalTime {
    public static void main(String[] args) {
        //0、获取本地时间对象
        LocalTime lt=LocalTime.now();//时分秒纳秒不可变的
        //1、获取时间中的信息
        int hour = lt.getHour();//时
        int minute = lt.getMinute();//分
        int second = lt.getSecond();//秒
        int nano = lt.getNano();//纳秒

        //2、修改时间:withHour、withMinute、withSecond、withNano
        LocalTime lt3 = lt.withHour(10);
        LocalTime lt4 = lt.withMinute(10);
        LocalTime lt5 = lt.withSecond(10);
        LocalTime lt6 = lt.withNano(10);

        //3、加多少:plusHours、plusMinutes、plusSeconds、plusNanos
        LocalTime lt7 = lt.plusHours(10);
        LocalTime lt8 = lt.plusMinutes(10);
        LocalTime lt9 = lt.plusSeconds(10);
        LocalTime lt10 = lt.plusNanos(10);

        //4、减多少:minusHours、minusMinutes、minusSeconds、minusNanos
        LocalTime lt11 = lt.minusHours(10);
        LocalTime lt12 = lt.minusMinutes(10);
        LocalTime lt13 = lt.minusSeconds(10);
        LocalTime lt14 = lt.minusNanos(10);
        // 5、获取指定时/可的LocalTime对象:
        // public static LocalTime of(int hour,int minute,int second)
        LocalTime lt15 = LocalTime.of(12,12,12);
        LocalTime lt16 = LocalTime .of(12,12,12);
        // 6、判 2个时/可对象,是否 在前还是在后:
        System.out.println(lt15.equals(lt16));
        System.out.println(lt15.equals(lt));
        System.out.println(lt15.equals(lt));
    }
}

Zoneld(时区ID)

时区:由于世界各个国家与地区的经度不同,各地区的时间也有所不同,因此会划分为不同的时区。世界标准时间(UTC)+ 8小时 = 中国标准时间

package com.itchinajie.d4_jdk8_time;

import java.time.Clock;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Test4_Zoneld_ZonedDateTime {
    public static void main(String[] args) {
        //目标:了解时区和带时区的时间。
        //1、ZoneId的常见方法:
        //public static ZoneId systemDefault():获取系统默认的时区
        ZoneId zoneId = ZoneId.systemDefault();
        System.out.println(zoneId.getId());
        System.out.println(zoneId);

        //public static Set<String>getAvailableZoneIds():获取Java支持的全部时区Id
        System.out.println(ZoneId.getAvailableZoneIds());

        //public static ZoneId of(String zoneId):把某个时区id封装成ZoneId,对象。
        ZoneId zoneId1 = ZoneId.of("America/New_York");

        //2、ZonedDateTime:带时区的时间。
        //public staticZonedDateTimenow(ZoneId zone):获取某个时区的ZonedDateTime对象。
        ZonedDateTime now = ZonedDateTime.now(zoneId1);
        System.out.println(now);
        //世界标准时间了
        ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());
        System.out.println(now1);
        //public static ZonedDateTimenow():获取系统默认时区的ZonedDateTime对象
        ZonedDateTime now2 = ZonedDateTime.now();
        System.out.println(now2);
        //Calendar instance = Calendar.getInstance(TimeZone.getTimeZone(zoneId1));
    }
}

代替Date

Instant时间戳/时间线

通过获取Instant的对象可以拿到此刻的时间,该时间由两部分组成:从1970-01-01 00:00:00 开始走到此刻的总秒数+不够1秒的纳秒数。

作用:可以用来记录代码的执行时间,或用于记录用户操作某个事件的时间点。
传统的Date类,只能精确到毫秒,并且是可变对象;
新增的Instant类,可以精确到纳秒,并且是不可变对象,推荐用Instant代替Date。

package com.itchinajie.d4_jdk8_time;

import java.time.Instant;

//目标:掌握instant的使用

public class Test5_instant {
    public static void main(String[] args) {
        //1、创建Instant的对象,获取此刻时间信息
        Instant now = Instant.now();//不可变对象

        //2、获取总秒数
        Long second = now.getEpochSecond();
        System.out.println(second);

        //3、不够1秒的纳秒数
        int nano = now.getNano();
        System.out.println(nano);

        System.out.println(now);

        Instant instant = now.plusNanos(111);

        //Instant对象的作用:做代码的性能分析,或者记录用户的操作时间点
        Instant now1 = Instant.now();
        //代码执行。。。。
        Instant now2 = Instant.now();
    }
}

代替SimpleDateFormat

DateTimeFormatter(日期时间格式化器)

package com.itchinajie.d4_jdk8_time;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/*
* 目标:掌握JDK8新增加的DateTimeFormatter格式化
* */
public class Test6_DateTimeFormatter {
    public static void main(String[] args) {
        //1、创建一个日期时间格式化器对象出来。
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM dd HH:mm:ss");

        //2、对时间进行格式化
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);

        String rs = formatter.format(now);//正向格式化
        System.out.println(rs);

        //3、格式化时间,其实还有一种方案。
        String rs2 = now.format(formatter);//反向格式化
        System.out.println(rs2);
        //4、解析时间:解析时间一般使用LocalDateTime提供的解析方法来解析。
        String datestr = "2029年12月12日12:12:11";
        LocalDateTime ldt = LocalDateTime.parse(datestr,formatter);
        System.out.println(ldt);
    }
}

其它补充

Period:计算时间间隔(年、月、日)

可以用于计算两个LocalDate对象相差的年数、月数、天数。

package com.itchinajie.d4_jdk8_time;

import java.time.Duration;
import java.time.LocalDateTime;

public class Test7_Period {
    public static void main(String[] args) {
        LocalDateTime start = LocalDateTime.of(2025,11, 11,10,10);
        LocalDateTime end = LocalDateTime.of(2025,11,11, 11,11,11);
        //1、得到Duration.对象
        Duration duration = Duration.between(start,end);

        //2、获取两个时间对象间隔的信息
        System.out.println(duration.toDays());//间隔多少天
        System.out.println(duration.toHours());//间隔多少小时
        System.out.println(duration.toMinutes());//间隔多少分
        System.out.println(duration.toSeconds());//间隔多少秒
        System.out.println(duration.toMillis());//间隔多少毫秒
        System.out.println(duration.toNanos());//间隔多少纳秒
    }
}

Duration:计算时间间隔(时、分、秒、纳秒)

可以用于计算两个时间对象相差的天数、小时数、分数、秒数、纳秒数;支持LocalTime、LocalDateTime、Instant等时间。

package com.itchinajie.d4_jdk8_time;

import java.time.LocalDate;
import java.time.Period;

/*
* 目标:掌握Period的作用:计算机两个日期相差的年数、月数、天数
* */
public class Test8_Duration {
    public static void main(String[] args) {
        LocalDate start = LocalDate.of(2029,8,10);
        LocalDate end = LocalDate.of(2029,12,15);

        //1、创建Period对象,封装两个日期对象。
        Period period = Period.between(start,end);

        //2、通过period.对象获取两个日期对象相差的信息。
        System.out.println(period.getYears());
        System.out.println(period.getMonths());
        System.out.println(period.getDays());
    }
}

Arrays类

用来操作数组的一个工具类。

package com.itchinajie.d5_arrays;

import java.util.Arrays;
import java.util.function.IntToDoubleFunction;

/*
* 目标:掌握Arrays类的常用方法
* */
public class ArraysTest1 {
    public static void main(String[] args) {
        //1、public static String toString(类型[] arr):返回数组的内容
        int[] arr = {10,20,30,40,50,60};
        System.out.println(Arrays.toString(arr));

        //2、public static int[] copyOfRange(类型[]arr,起始索引,结束索引):拷贝数组(指定范围,包前不包后)
        int[] arr2 = Arrays.copyOfRange(arr,1,4);
        System.out.println(Arrays.toString(arr2));

        //3、public static copyOf(类型[] arr,int newLength);拷贝数组,可以指定新数组的长度。
        int[] arr3 = Arrays.copyOf(arr,10);
        System.out.println(Arrays.toString(arr3));

        //4、public static setAll(double[] array,IntToDoubleFunction generator):把数组中的原数据改为新数据又存进去。
        double[] prices = {99.8,128,100};
        //把所有的价格都打八折,然后又存进去
        Arrays.setAll(prices, new IntToDoubleFunction() {
            @Override
            public double applyAsDouble(int value) {
                return prices[value] * 0.8;
            }
        });
        System.out.println(Arrays.toString(prices));
        //5、public static void sort(类型[]arr):对数组进行排序(默认是升序排序)
        Arrays.sort(prices);
        System.out.println(Arrays.toString(prices));
    }
}

对数组中的数据进行排序

如果数组中存储的是对象,如何排序?

方式一:让该对象的类实现Comparable(比较规则)接口,然后重写compareTo方法,自己来制定比较规则。
方式二:使用下面这个sort方法,创建Comparator比较器接口的匿名内部类对象,然后自己制定比较规则。
public static<T>void sort(T[] arr,Comparator<?super T>c)对数组进行排序(支持自定义排序规则)。

自定义排序规则时,需要遵循的官方约定如下:

如果认为左边对象大于右边对象应该返回正整数;
如果认为左边对象小于右边对象应该返回负整数;
如果认为左边对象等于右边对象应该返回0整数。

package com.itchinajie.d5_arrays;

import java.util.Arrays;
import java.util.Comparator;

public class ArrayTest2 {
    public static void main(String[] args) {
        //目标:掌握如何对数组中的对象进行排序。
        Student[] students = new Student[4];
        students[0] = new Student("蜘蛛精",169.5,23);
        students[1] = new Student("紫霞",163.8,26);
        students[2] = new Student("紫霞",163.8, 26);
        students[3] = new Student("至尊宝",167.5,24);
        //1、public static void sort(类型[] arr):对数组进行排序。
//        Arrays.sort(students);
//        System.out.println(Arrays.toString(students));
        //2.public static <T>void sort(T[] arr,Comparator <? super T>c)

        //参数一:需要排序的数组
        //参数二:Comparator.比较器对象(用来制定对象的比较规则)
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //指定比较规则了:左边对象 o1  右边对象 o2
                //约定1:如果左边的对象 大于 右边对象 请您返回正整数
                //约定2:如果左边的对象 小于 右边对象 请您返回负整数
                //约定3:如果左边的对象 等于 右边对象 请您一定返回0
//                if (o1.getHeight() > o2.getHeight()) {
//                    return 1;
//                } else if (o1.getHeight() < o2.getHeight()) {
//                    return -1;
//                }
//                return 0;//升序
                return Double.compare(o1.getHeight(),o2.getHeight());//升序
                //return Double.compare(o2.getHeight(),o1.getHeight());//降序
            }
        });
        System.out.println(Arrays.toString(students));
    }
}




package com.itchinajie.d5_arrays;

public class Student implements Comparable<Student>{
    private String name;
    private double height;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Student() {
    }

    public Student(String name, double height, int age) {
        this.name = name;
        this.height = height;
        this.age = age;
    }
   //制定比较规则
    @Override
    public int compareTo(Student o) {
        //约定1:  如果左边的对象 大于 右边对象 请您返回正整数
        //约定2:  如果左边的对象 小于 右边对象 请您返回负整数
        //约定3:  如果左边的对象 等于 右边对象 请您返回0
        //按照年龄升序排序
//        if (this.age > o.age) {
//            return 1;
//        }else if (this.age < o.age){
//            return -1;
//        }
//        return 0;
        //return this.age - o.age;//升序
        return o.age - this.age;//降序
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", age=" + age +
                '}';
    }
}

JDK8新特性:Lambda表达式

Lambda表达式是IDK8开始新增的一种语法形式;作用:用于简化匿名内部类的代码写法。

注意:Lambda表达式只能简化函数式接口的匿名内部类!!

什么是函数式接口?

有且仅有一个抽象方法的接口。
注意:将来我们见到的大部分函数式接口,上面都可能会有一个@Functionallnterface的注解有该注解。

package com.itchinajie.d6_lambda;

public class LambdaTest1 {
    public static void main(String[] args) {
        //目标:认识Lambda表达式
//        Animal a = new Animal() {
//            @Override
//            public void run() {
//                System.out.println("狗跑的贼快~~");
//            }
//        };
//        a.run();

        //注意:Lambda表达式不是说能简化全部匿名内部类的写法,只能简化函数式接口的匿名内部类
        //错误代码!
//        Animal a = () ->{
//            System.out.println("狗跑的贼快~~");
//        };
//        a.run();

//        Swimming s = new Swimming() {
//            @Override
//            public void swim() {
//                System.out.println("学生快乐的游泳~~");
//            }
//        };
//        s.swim();

        Swimming s = () ->{
            System.out.println("学生快乐的游泳~~");
        };
        s.swim();

    }
}
interface Swimming{
    void swim();
}

abstract class Animal{
    public abstract void run();
}

Lambda表达式的省略写法(进一步简化Lambda表达式的写法)

参数类型可以省略不写。
如果只有一个参数,参数类型可以省略,同时)也可以省略。
如果Lambda表达式中的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号!此时,如
果这行代码是return语句,也必须去掉return不写。

package com.itchinajie.d6_lambda;

import com.itchinajie.d5_arrays.Student;

import java.util.Arrays;

public class LambdaTest2 {
    public static void main(String[] args) {
        int[] arr = {10,20,30,40,50,60};
        System.out.println(Arrays.toString(arr));
        int[] arr2 = Arrays.copyOfRange(arr,1,4);
        System.out.println(Arrays.toString(arr2));
        int[] arr3 = Arrays.copyOf(arr,10);
        System.out.println(Arrays.toString(arr3));
        double[] prices = {99.8,128,100};
//        Arrays.setAll(prices, new IntToDoubleFunction() {
//            @Override
//            public double applyAsDouble(int value) {
//                return prices[value] * 0.8;
//            }
//        });
        //Lambda简化
//        Arrays.setAll(prices,(value) ->  {
//                return prices[value] * 0.8;
//        });
        //再简化
        Arrays.setAll(prices,(value) -> prices[value] * 0.8);

        System.out.println(Arrays.toString(prices));
        Arrays.sort(prices);
        System.out.println(Arrays.toString(prices));
        Student[] students = new Student[4];
        students[0] = new Student("蜘蛛精",169.5,23);
        students[1] = new Student("紫霞",163.8,26);
        students[2] = new Student("紫霞",163.8, 26);
        students[3] = new Student("至尊宝",167.5,24);

//        Arrays.sort(students, new Comparator<Student>() {
//            @Override
//            public int compare(Student o1, Student o2) {
//                return Double.compare(o1.getHeight(),o2.getHeight());//升序
//                //return Double.compare(o2.getHeight(),o1.getHeight());//降序
//            }
//        });
        //Lambda简化后的形式
        Arrays.sort(students, ( o1,  o2) -> Double.compare(o1.getHeight(),o2.getHeight()));//升序
        System.out.println(Arrays.toString(students));
    }
}

JDK8新特性:方法引用

静态方法的引用

类名::静态方法。
使用场景:
如果某个Lambda表达式里只是调用一个静态方法,并且前后参数的形式一致,就可以使用静态方法引用。

实例方法的引用

对象名::实例方法。
使用场景:
如果某个Lambda表达式里只是调用一个实例方法,并且前后参数的形式一致,就可以使用实例方法引用。

静态方法的引用

类名::静态方法。
使用场景
如果某个Lambda表达式里只是调用一个静态方法,并且前后参数的形式一致,就可以使用静态方法引用。

构造器引用

类名::new
使用场景
如果某个Lambda表达式里只是在创建对象,并且前后参数情况一致,就可以使用构造器引用。

(本章图片均来自于黑马程序员视频)

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值