jdk1.8新特性(1)

接口增强

接口中default、static关键字可以有方法体,可以实现逻辑

public interface People {
    //不需要被实现,当然也可以实现
    default void eat(){
        System.out.println("我是接口中eat方法,在吃东西");
    }
    //无法实现
    static void dirnk(){
        System.out.println("我是接口中dirnk方法,在喝东西");
    }
    //子类必须实现
    void play();
}

base64

public class New {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String spring = "我们都是神枪手";
        Base64.Decoder decoder = Base64.getDecoder();
        Base64.Encoder encoder = Base64.getEncoder();
        //编码
        String encodeToString = encoder.encodeToString(spring.getBytes("UTF-8"));
        System.out.println(encodeToString);
        //解码
        System.out.println(new String(decoder.decode(encodeToString), "UTF8"));
    }
}

日期时间类

LocalDate:不包含具体时间的⽇期。
LocalTime:不含⽇期的时间。
LocalDateTime:包含了⽇期及时间。

package com.example.demo.jdl8;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

public class DateUtils {

    Logger logger = LoggerFactory.getLogger(DateUtils.class);

    @Test
    public  void test() {
        LocalDate now = LocalDate.now();
        logger.info(String.format("当前时间:%s",now));
        logger.info(String.format("现在是哪年:%s",now.getYear()));
        logger.info(String.format("现在是哪⽉:%s",now.getMonth()));
        logger.info(String.format("现在是哪⽉(数字):%s",now.getMonthValue()));
        logger.info(String.format("现在是⼏号:%s",now.getDayOfMonth()));
        logger.info(String.format("现在是周⼏:%s",now.getDayOfWeek()));
        logger.info(String.format("现在是今年第几天:%s",now.getDayOfYear()));

        logger.info("-------------------------------------------------------------");
        //localdate 转 date
        //获取时间地区ID
        ZoneId zoneId = ZoneId.systemDefault();
        //转换为当地时
        ZonedDateTime zonedDateTime = now.atStartOfDay().atZone(zoneId);
        //转为Date类型
        Date nows = Date.from(zonedDateTime.toInstant());
        logger.info(String.format("转化后的date时间:%s",nows));

        //date 转 localdate
        Date date = new Date();
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        LocalDate localDate = localDateTime.toLocalDate();
        logger.info(String.format("再转化后的local date时间:%s",localDate));

        logger.info("-------------------------------------------------------------");
        LocalDate changeDate = localDate.plusYears(1);
        logger.info("加1年后是哪年:"+changeDate.getYear());
        logger.info("旧的是哪年:"+localDate.getYear());

        logger.info("判断日期先后: "+changeDate.isAfter(localDate));

        logger.info("-------------------------------------------------------------");
        LocalDate change = now.withYear(1990);//设置当前日期的年分为1990年
        LocalDate localDate1 = change.withMonth(1);//设置当前日期的月份 1月
        LocalDate localDate2 = localDate1.withDayOfMonth(1); //设置当前日期的日期为1号
        logger.info("修改后的日期: "+localDate2);

        LocalDate localDate3 = localDate2.withDayOfYear(360);
        logger.info("当前年份360天是哪天: "+localDate3);

        //plusYears(long yearsToAdd) LocalDate 当前对象增加指定的年份数
        //plusMonths(long monthsToAdd) LocalDate 当前对象增加指定的⽉份数
        //plusWeeks(long weeksToAdd) LocalDate 当前对象增加指定的周数
        //plusDays(long daysToAdd) LocalDate 当前对象增加指定的天数
        //minusYears(long yearsToSubtract) LocalDate 当前对象减去指定的年数
        //minusMonths(long monthsToSubtract) LocalDate 当前对象减去注定的⽉数
        //minusWeeks(long weeksToSubtract) LocalDate 当前对象减去指定的周数
        //minusDays(long daysToSubtract) LocalDate 当前对象减去指定的天数
        //compareTo(ChronoLocalDate other) int ⽐较当前对象和other对象在时间上的⼤⼩,返回值如果为正,则当前对象时间较晚,
        //isBefore(ChronoLocalDate other) boolean ⽐较当前对象⽇期是否 other对象⽇期之前
        //isAfter(ChronoLocalDate other) boolean ⽐较当前对象⽇期是否在 other对象⽇期之后
        //isEqual(ChronoLocalDate other) boolean ⽐较两个⽇期对象是否相等

        //local date 与字符串转化
        LocalDateTime dateTime = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String string = dateTimeFormatter.format(dateTime);
        logger.info("local date time 转字符串:"+string);
        logger.info("-------------------------------------------------------------");
        LocalDateTime date1 = LocalDateTime.of(2020, 1, 1, 1, 1, 1);
        logger.info("根据指定年月日时分秒获取LocalDateTime对象:"+date1.toString())
        LocalDateTime date2 = LocalDateTime.of(2020,12,1,1,1,1);
        logger.info("根据指定年月日时分秒获取LocalDateTime对象:"+date2.toString());

        Duration duration = Duration.between(date1,date2);//第⼆个参数减第⼀个参数
        logger.info(String.format("两个时间差的天数:%s",duration.toDays()));
        logger.info(String.format("两个时间差的⼩时数:%s",duration.toHours()));
        logger.info(String.format("两个时间差的分钟数:%s",duration.toMinutes()));
        logger.info(String.format("两个时间差的毫秒数:%s",duration.toMillis()));
        logger.info(String.format("两个时间差的纳秒数:%s",duration.toNanos()));
    }
}

结果

11:04:41.976 [main] INFO com.example.demo.jdl8.DateUtils - 当前时间:2020-09-05
11:04:41.980 [main] INFO com.example.demo.jdl8.DateUtils - 现在是哪年:2020
11:04:41.980 [main] INFO com.example.demo.jdl8.DateUtils - 现在是哪⽉:SEPTEMBER
11:04:41.980 [main] INFO com.example.demo.jdl8.DateUtils - 现在是哪⽉(数字):9
11:04:41.980 [main] INFO com.example.demo.jdl8.DateUtils - 现在是⼏号:5
11:04:41.980 [main] INFO com.example.demo.jdl8.DateUtils - 现在是周⼏:SATURDAY
11:04:41.981 [main] INFO com.example.demo.jdl8.DateUtils - 现在是今年第几天:249
11:04:41.981 [main] INFO com.example.demo.jdl8.DateUtils - -------------------------------------------------------------
11:04:41.984 [main] INFO com.example.demo.jdl8.DateUtils - 转化后的date时间:Sat Sep 05 00:00:00 CST 2020
11:04:41.984 [main] INFO com.example.demo.jdl8.DateUtils - 再转化后的local date时间:2020-09-05
11:04:41.984 [main] INFO com.example.demo.jdl8.DateUtils - -------------------------------------------------------------
11:04:41.985 [main] INFO com.example.demo.jdl8.DateUtils -1年后是哪年:2021
11:04:41.985 [main] INFO com.example.demo.jdl8.DateUtils - 旧的是哪年:2020
11:04:41.985 [main] INFO com.example.demo.jdl8.DateUtils - 判断日期先后: true
11:04:41.985 [main] INFO com.example.demo.jdl8.DateUtils - -------------------------------------------------------------
11:04:41.985 [main] INFO com.example.demo.jdl8.DateUtils - 修改后的日期: 1990-01-01
11:04:41.985 [main] INFO com.example.demo.jdl8.DateUtils - 当前年份360天是哪天: 1990-12-26
11:04:41.997 [main] INFO com.example.demo.jdl8.DateUtils - local date time 转字符串:2020-09-05 11:04:41
11:04:41.998 [main] INFO com.example.demo.jdl8.DateUtils - -------------------------------------------------------------
11:04:41.998 [main] INFO com.example.demo.jdl8.DateUtils - 根据指定年月日时分秒获取LocalDateTime对象:2020-01-01T01:01:01
11:04:41.998 [main] INFO com.example.demo.jdl8.DateUtils - 根据指定年月日时分秒获取LocalDateTime对象:2020-12-01T01:01:01
11:04:41.998 [main] INFO com.example.demo.jdl8.DateUtils - 两个时间差的天数:335
11:04:41.998 [main] INFO com.example.demo.jdl8.DateUtils - 两个时间差的⼩时数:8040
11:04:41.998 [main] INFO com.example.demo.jdl8.DateUtils - 两个时间差的分钟数:482400
11:04:41.998 [main] INFO com.example.demo.jdl8.DateUtils - 两个时间差的毫秒数:28944000000
11:04:41.999 [main] INFO com.example.demo.jdl8.DateUtils - 两个时间差的纳秒数:28944000000000000

Optional

主要解决的问题是空指针异常,增加一些兜底方案,增加了一些链式调用,配合lambda表达式代码看起来更加简洁。

public class OptionalUtils {

    public static void main(String[] args) {
        String s = "Chinese";
        Optional<String> optional = Optional.ofNullable(s);


        Student student = null;
        //第一种用法  如果为空会报空指针异常
        Optional.of(student);
        //第二种用法 如果为空会抛出自定义异常信息
        Optional.ofNullable(student).orElseThrow(()->new RuntimeException("对象为空"));
        //第三种用法 如果对象为空返回一个新的对象
        Optional.ofNullable(student).orElse(new Student());
        //第四种用法 如果对象为空返回一个新的对象
        Optional.ofNullable(student).orElseGet(()->new Student());
        //提供者接口
        Optional.ofNullable(student).orElseGet(()->{
            Student stu = new Student();
            stu.setAddr(1);
            return stu;
        });
        //写一个变种方法 写一个方法的函数调用
        Optional.ofNullable(student).orElseGet(OptionalUtils::getStudent);
        //第五种用法  如果对象不为空执行逻辑   打印出用户的年龄
        Optional.ofNullable(student).ifPresent(a->{
            System.out.println(a.getAge());
        });
        //第六种用法
        //对象引用一致调用,如果不为空可以一致调用
        Optional.ofNullable(student).map(a->a.getTeacher()).map(a->a.getPeople()).map(a->a.name);
        //获取到名字
        Optional.ofNullable(student).map(a->a.getTeacher()).map(a->a.getPeople()).map(a->a.name).get();
        //获取兜底信息,如果其中任何一个为空,直接返回兜底数据
        Optional.ofNullable(student).map(a->a.getTeacher()).map(a->a.getPeople()).map(a->a.name).orElse("张飞");

        //第七种用法 如果对象不为空并且名字等于张飞 直接返回  如果不等于张飞可以返回一个新的对象
        Optional.ofNullable(student).filter(a->a.getName().equals("张飞")).orElse(new Student());

        //如果值存在则isPresent()⽅法会返回true
        System.out.println(String.format("对象是否为null:%s",!optional.isPresent()));
        System.out.println(String.format("对象内容为:%s",optional.get()));
    }

    public static Student getStudent(){
        return new Student();
    }

    static class Student{
        int age;
        String name;
        int addr;
        int num;
        Teacher teacher;

        public Student() {
        }

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

        public int getAge() {
            return age;
        }

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

        public String getName() {
            return name;
        }

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

        public int getAddr() {
            return addr;
        }

        public void setAddr(int addr) {
            this.addr = addr;
        }

        public int getNum() {
            return num;
        }

        public void setNum(int num) {
            this.num = num;
        }

        public Teacher getTeacher() {
            return teacher;
        }

        public void setTeacher(Teacher teacher) {
            this.teacher = teacher;
        }
    }

    static class Teacher{
        People people;

        public People getPeople() {
            return people;
        }

        public void setPeople(People people) {
            this.people = people;
        }
    }

    static class  People{
        String name;

        public String getName() {
            return name;
        }

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

result

对象是否为null:false
对象内容为:Chinese
s1为空,兜底内容:hello world
如果为空就取默认值:默认值
如果不为空就取原值:李萍

Lambda表达式

函数式编程:可理解是将⼀个函数作为⼀个参数进⾏传递, 而lambdm表达式会使函数书写更加简洁,我们只需要将lambdm当作参数传递即可。

lambda简单demo

lambda表达式:⼀个接⼝中只包含⼀个⽅法,则可以使⽤Lambda表达式,这样的接⼝称之为“函数接⼝”。接口中最好有@FunctionalInterface注解,防止定义其它方法导致出现问题。

语法:

第⼀部分为括号内⽤逗号分隔的形式参数,参数是函数式接⼝⾥⾯⽅法的参数;
第⼆部分为⼀个箭头符号:->;第三部分为⽅法体,可以是表达式和代码块

参数列表 :
括号中参数列表的数据类型可以省略不写
括号中的参数只有⼀个,那么参数类型和()都可以省略不写

方法体
如果{}中的代码只有⼀⾏,⽆论有返回值,可以省略{},return,分号,要⼀起省略,其他则需要加上

    public static void main(String[] args) {
        //使用lambdm创建线程
        Thread thread = new Thread(() -> System.out.println("线程方法"));
        thread.start();
        //使用lambdm对集合进行排序
        ArrayList<String> strings = Lists.newArrayList("a", "c", "d", "b", "e", "f", "h", "g", "a");
        Collections.sort(strings,(a,b)->{
            return a.compareTo(b);
        });
        System.out.println(strings);
    }

自定义函数式接口并调用

定义一个接口,函数式接口,只有一个方法,防止出错增加@FunctionalInterface注解。

/**
 * 定义一个函数式接口
 * 逻辑需要我们自己定义,该接口只是执行
 * 我们需要把这个接口当作参数传递,具体逻辑在参数调用时候书写
 * @param <T>
 * @param <K>
 */
@FunctionalInterface
interface Func<T,K>{

    public K get(T t1,T t2);

}

直接上demo,例子中注释已详细说明了函数调用过程。

public class Lambda {
    public static void main(String[] args) {
        //定义函数式接口中函数的逻辑,需要用它当作参数传递
        Func<String,String> func = (a,b)->a.toUpperCase() + "-" + b.toUpperCase();
        String s1  = "jack";
        String s2  = "jack is a good man";
        //形式 1
        //String execute = execute((a, b) -> a.toUpperCase() + "-" + b.toUpperCase(), s1, s2);
        String execute = execute(func, s1, s2);
        System.out.println(execute);
        System.out.println("********************************************");
        //可以执行很多工具方法的函数,我们我们传递某些工具类
        //普通方法的函数调用,调用common包的remove方法,函数式调用
        //注意,方法转函数的时候,参数、返回值必须与func(函数式接口)一致
        //这个方法符合咱们定义的函数式接口  (string,string) 返回值 (string)
        // String remove = StringUtils.remove(s1, s2);
        Func<String, String> removeAll = StringUtils::removeAll;
        String execute2 = execute(removeAll, s2, s1);
        System.out.println("方法的函数调用(删除了s2的jack):"+execute2);

        //小技巧
        System.out.println("普通方法的函数执行");
        TriFunction<Func<String, String>, String, String, String> execute1 = Lambda::execute;
        String apply = execute1.apply(func, s1, s2);
        System.out.println(apply);
    }

    /**
     * 函数式接口具体方法(执行)
     * @param func  函数式参数,函数式编程
     * @param s1  代表函数式接口的第一个参数
     * @param s2  代表函数式接口的第二个参数
     *            当然我们也可以定义其他参数
     */
    public static String execute(Func<String,String> func,String s1,String s2){
        //对你定义的函数式逻辑执行,就是执行
        // Func<String,String> func = (a,b)->a.toUpperCase() + "-" + b.toUpperCase();
        String s = func.get(s1, s2);
        //可以执行你自己的业务逻辑
        //**********************************
        //返回
        return s;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值