Java 8的关键新特性:Lambda表达式、Base64编码、日期时间API及Optional类

3 篇文章 0 订阅

简介

自从Java 8发布以来,它就标志着Java编程语言的一个重要转折点。这一版本不仅带来了诸多功能上的改进,还引入了一些革命性的特性,彻底改变了开发者编写代码的方式。Java 8的设计目标是让语言更加简洁、更具表现力,并且能够更好地适应多核处理器时代的需求。本文将探讨Java 8中最值得关注的新特性,包括Lambda表达式、Stream API、新的日期与时间API以及Optional类等。下面我们来用代码来实现这些新增的属性:

JDK加解密

jdk8之前使用jdk里sun.misc套件里的Base64Encode和Base64Decode加解密缺点:编码和解码的效率比较差;引入apache commons codec有提供base64的编码和解码:
缺点是需要引入apache commons codec;jdk8在java.util包中新增了Base64类用于编码解码,Base64类提供了直接可用的静态方法,如Base64.getEncoder()和Base64.getDecoder(),使得编码和解码变得非常直观和简单。开发者不需要手动管理编码器和解码器实例,减少了出错的机会。

代码实现​:



public class JdkEncode {
    public static void main(String[] args) throws IOException {//jdk8之前
        BASE64Encoder encoder = new BASE64Encoder();
        BASE64Decoder decoder = new BASE64Decoder();
        String text = "hello world";
        byte[] bytes = text.getBytes("UTF-8");
        //编码
        String encode = encoder.encode(bytes);
        System.out.println("编码:"+encode);
        //解码
        System.out.println("解码:"+new String(decoder.decodeBuffer(encode),"UTF-8"));//jdk8
        Base64.Decoder decoder1 = Base64.getDecoder();
        Base64.Encoder encoder1 = Base64.getEncoder();byte[] encode1 = encoder1.encode(bytes);
        System.out.println("编码:"+encode1);
        System.out.println("解码:"+new String(decoder1.decode(encode1),"UTF-8"));}}

Lambda 表达式:函数式编程的入口

Java 8中最令人兴奋的特性之一无疑是Lambda表达式。这一特性允许开发者以一种简洁的方式定义匿名函数,并将其作为方法参数传递。
函数编程:将一个函数作为一个参数进行传递,面向对象是对数据的抽象,而函数式编程则是对行为的抽象。

lambda表达式使用场景:一个接口只包含一个方法,则可以使用lambda表达式,这个接口称之为函数式接口

java内置的四大核心函数式接口

  • consumer消费型接口:有入参,无返回值,void accept(T t)
  • Supplier供给型接口:无入参,有返回值,T get()
  • Function函数型接口:有入参,有返回值, R apply(T t)
  • Predicate段言型接口,有入参,有返回值,返回值类型为boolean boolean test(T t)

代码实现


 /**
     * 初识函数式
     */
    public static void test1(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("传统方式创建线程");
            }
        });//使用lambda表达式
        new Thread(()-> System.out.println("函数式编程创建线程"));
    }/**
     * 集合排序
     */
    public static void testList(){
        List<String> list = Arrays.asList("aaa","bbb","ccc");
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.compareTo(o1);
            }
        });
        for (String s : list) {
            System.out.println(s);
        }//lambda表达式实现
        List<String> list1 = Arrays.asList("aaa","fff","ggg","ddd");
        Collections.sort(list1,(a,b)->b.compareTo(a));
        list1.forEach(System.out::println);
    }/**
     * 自定义函数接口
     */
    public static void testFunction(){
        System.out.println(operator(20,5,(Integer x,Integer y)->{
            return x*y;
        }));System.out.println(operator(20,5,(x,y)->{
            return x-y;
        }));
        System.out.println(operator(20,5,(x,y)->{
            return x+y;
        }));
        System.out.println(operator(20,5,(x,y)->{
            return x/y;
        }));
    }/**
     * 自定义函数式接口
     * @param x
     * @param y
     * @param operFunction
     * @return
     */
    public static Integer operator(Integer x,Integer y,OperFunction<Integer,Integer>operFunction){
        return operFunction.operator(x,y);
    }/**
     * 传递多个参数bifunction
     */
    public static void testBiFunction(){
        System.out.println(biFunctionOperator(20,5,(x,y)->x*y));
        System.out.println(biFunctionOperator(20,5,(x,y)->x/y));
        System.out.println(biFunctionOperator(20,5,(x,y)->x+y));
        System.out.println(biFunctionOperator(20,5,(x,y)->x-y));
    }public static Integer biFunctionOperator(Integer x,Integer y,BiFunction<Integer,Integer,Integer>biFunction){
        return biFunction.apply(x,y);
    }
    
    
自定义函数式接口

@FunctionalInterface
public interface BiFunction <T,U,R>{
    R apply(T t,U u);
}@FunctionalInterface
public interface OperFunction <R,T>{R operator(T t1,T t2);
}

日期与时间API:面向未来的日期处理

Java 8引入了一个全新的日期和时间API,它位于java.time包中。这个API解决了旧版Date和Calendar类中存在的许多问题,并提供了更为丰富和一致的功能集。新的API不仅更易于使用,而且完全线程安全,并且能够更好地适应不同的时区和地区设置。
jdk8发布的Date-time api来进一步加强对日期与时间的处理; 新增了很多常见的api,如日期/时间的比较,加减,格式化等;​ 位于java.time​中

核心类:

  • localDate:不包含具体时间的日期
  • ​localTime: 不包含日期的时间
  • ​localDateTime:包含日期和时间​

代码实现:

public class JdkTime {public static void main(String[] args) {formatterTime();//获取当前日期
        LocalDate now = LocalDate.now();
        System.out.println("当前日期:"+now);//获取年月日周期
        System.out.println("当前年:"+now.getYear());
        System.out.println("当前月:"+now.getMonth());
        System.out.println("当前月:"+now.getMonthValue());
        System.out.println("当前日:"+now.getDayOfMonth());
        System.out.println("当前周几:"+now.getDayOfWeek().getValue());//加减年份,加后返回的对象才是修改后的,旧的依旧是旧的
        LocalDate localDate = now.plusYears(1);
        System.out.println("加后的年份:"+localDate);//日期比较
        System.out.println("isAfter:"+localDate.isAfter(now));
        System.out.println("isBefore:"+localDate.isBefore(now));//getYear() int 获取当前⽇期的年份
        //getMonth() Month 获取当前⽇期的⽉份对象
        //getMonthValue() int 获取当前⽇期是第⼏⽉
        //getDayOfWeek() DayOfWeek 表示该对象表示的⽇期是星期⼏
        //getDayOfMonth() int 表示该对象表示的⽇期是这个⽉第⼏天
        //getDayOfYear() int 表示该对象表示的⽇期是今年第⼏天
        //withYear(int year) LocalDate 修改当前对象的年份
        //withMonth(int month) LocalDate 修改当前对象的⽉份
        //withDayOfMonth(int dayOfMonth) LocalDate 修改当前对象在当⽉的⽇期
        //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 ⽐较两个⽇期对象是否相等
    }/**
     * 时间日期格式化
     */
    public static void formatterTime(){
        //jdk8之前使用simpleDateFormat进行格式化,simpleDateFormat不是线程安全的
        //jdk8之后使用线程安全的DateTimeFormatterLocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);
        //格式化
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String ldfStr = dateTimeFormatter.format(localDateTime);
        System.out.println(ldfStr);//获取指定的日期时间
        LocalDateTime localDateTime1 = LocalDateTime.of(2024, 07, 15, 16, 26, 30);
        System.out.println(localDateTime1);//计算日期时间差java.time.durationLocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        LocalDateTime localDateTime2 = LocalDateTime.of(2023, 12, 12, 12, 12, 12);
        System.out.println(localDateTime2);
        //第二个参数减第一个参数
        Duration duration = Duration.between(localDateTime2, now);
        //两个时间差的天数
        System.out.println(duration.toDays());
        //小时数
        System.out.println(duration.toHours());
        //分钟
        System.out.println(duration.toMinutes());
        //毫秒
        System.out.println(duration.toMillis());
        //纳秒
        System.out.println(duration.toNanos());
    }
}

Optional 类:更优雅地处理null

在Java中处理null值一直是一个常见的陷阱,容易引发NullPointerException。为了解决这个问题,Java 8引入了Optional类。Optional是一个可以为null的容器对象,如果值存在则持有该值,否则持有null。使用Optional可以有效地避免空指针异常,并鼓励良好的编程实践。
本质:optional包含一个可选值的包装类,意味着optional类既可以含有对象也可以为空

创建optional类

  • of() null值为参数传递进入,会抛出异常
  • ofNullable(),对象可为null,也可不为null
  • isPresent判断值是否存在
  • get()获取对象
  • orElse()如果有值则返回该值,否则返回传递给它的参数值

代码实现

public class JdkOptional {
    public static void main(String[] args) {//创建Optional
        User user = null;
        User user1 = new User(1L,"jack",11);
//        Optional<User> optional = Optional.of(user);Optional<User> optional1 = Optional.ofNullable(user);User user3 = Optional.ofNullable(user).orElse(user1);//获取optional对象的值get()
        //如果值存在则isPresent()方法会返回true,调用get方法会返回该对象,
        //一般使用get之前需要先验证是否有值,不然还会报错
        if (optional1.isPresent()){
            User user2 = optional1.get();
            System.out.println(user2);
        }
        System.out.println(user3.getId());
        Long aLong = Optional.ofNullable(user1).map(obj -> obj.getId()).orElse(4L);
        System.out.println(aLong);
    }
}

Java 8引入的这些特性极大地简化了日常的开发任务,提高了代码的可读性和可维护性。无论是通过Lambda表达式来简化函数式编程,还是通过新的日期时间API来处理复杂的日期计算,亦或是通过Optional类来优雅地处理null值,都表明了Java语言正朝着更加现代化的方向发展。希望本文能帮助您更好地理解和应用这些新特性。
更多内容请关注以下公众号
在这里插入图片描述

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

double_lifly

点喜欢就是最好的打赏!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值