Java8

Lambda表达式

Lambda表达式在java语言中引入了一种新的语法元素和操作符号:“->”,它将Lambda表达式分割为两部分。
左边:指Lambda表达式的所有参数 。
右边:指Lambda体,即表示Lambda表达式需要执行的功能。

    volumes.forEach(volume -> {
            volume.setFql(String.valueOf(DateUtil.thisYear()));
        });

LambdaQueryWrapper

LambdaQueryWrapper是MyBatis-Plus提供的一种查询构建器,可以通过Lambda表达式来构建查询条件,使用起来比传统的SQL语句更加简洁和易读。
 

LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
userWrapper.in(SysUser::getOrgCode, tyywConfig.getAjdw());
List<SysUser> sysUsers = userService.list(userWrapper);
sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, s -> s, (v1, v2) -> v2));

方法引用和构造器引用

使用操作符“::”将方法名和对象或者类分割开来

(x) -> System.out.println(x);
//等同于:
System.out::println;
Map<String, List<SmsRecord>> groupByMap = smsRecords.stream().collect(Collectors.groupingBy(SmsRecord::getLxbm));

函数式接口

@FunctionalInterface
public interface CacheConsumer {

    /**
     * 执行业务处理
     *
     * @return
     */
    Object execute();
}


这段代码定义了一个函数式接口 CacheConsumer,它包含一个抽象方法 execute(),用于执行业务处理并返回结果。让我逐步解释它:

@FunctionalInterface: 这是一个注解,用于标记该接口为函数式接口。函数式接口是只包含一个抽象方法的接口,它们可以被Lambda表达式所代替。
public interface CacheConsumer { ... }: 这是接口的定义,名为 CacheConsumer。
Object execute();: 这是接口中的抽象方法,用于执行业务处理逻辑。它没有参数,并且返回类型为 Object。具体的业务处理逻辑由实现该接口的类来实现。
通过定义这样一个函数式接口,可以将业务处理逻辑封装在一个接口中,然后在需要的地方通过实现该接口来传递具体的业务逻辑。这种方式可以使代码更加灵活,易于维护和扩展。

Stream API

Stream API(java.util.stream.*)大大简化了在编程中对于集合的处理,可以对集合执行非常复杂的查找、过滤和映射数据等操作。

List<TyywZrrjbxxDTO> collectXyrxxList = zrrxxList.stream().filter(e -> "0009000900001".equals(e.getZrrlxdm())).collect(Collectors.toList());

List<String> xyrList = collectXyrxxList.stream().map(TyywZrrjbxxDTO::getXm).collect(Collectors.toList());

LocalDateTime

1.更加丰富的日期时间类型支持:LocalDateTime 类封装了 LocalDate 和 LocalTime 两个类,支持更加细化的日期时间操作,例如获取某一天的开始和结束时间、获取某个时间段内的所有日期等。

2.线程安全性:LocalDateTime 类是不可变对象,线程安全性较高,可以在多线程环境下安全使用。

3.时区支持:LocalDateTime 类在处理时区相关的操作时有着很好的支持,例如可以将一个 LocalDateTime 对象转换成 ZonedDateTime 对象,以支持更加复杂的时区计算。

LocalDateTime localDateTime1 = LocalDateTime.now();

                                    ajFsdx.setFsdxsjNext(LocalDateTime.now().plus(Constants.JRZC_TB_FL_INTERVAL, ChronoUnit.DAYS));


return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());

反射

 Java的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制。

反射的应用场景

反射是Java框架的灵魂技术,很多框架都使用了反射技术,如spring,Mybatis,Hibernate等。 

JDBC的数据库的连接
在JDBC连接数据库中,一般包括加载驱动,获得数据库连接等步骤。而加载驱动,就是引入相关Jar包后,通过Class.forName()加载数据库的驱动程序。
xml或properties等配置文件加载
Spring 通过 XML 配置模式装载Bean,也是反射的一个典型例子。装载过程:
.将程序内XML配置文件加载入内存中
.Java类解析xml或者properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息
·使用反射机制,得到Class实例
·动态配置实例的属性
反射的优点
动态性:反射提供了在运行时动态地探索和操作类的能力。它允许我们在运行时获取类的信息、创建对象、调用方法和修改字段的值,从而使程序更加灵活、可扩展和动态。
适应复杂环境::反射可以应对一些复杂的场景,如在插件化系统中根据配置文件加载类、动态代理、识别和处理注解等。
反射的缺点
性能问题:由于反射涉及到动态解析和调用,所以它通常比直接调用代码性能较低。反射需要进行额外的检查和处理,可能会导致性能下降。
安全问题:反射可以绕过访问控制限制,例如访问私有方法和字段。这可能会导致安全隐患。

动态代理

动态代理实现方式:
JDK实现:JDK Proxy基于反射
第三方类实现:CGLIB基于ASM (一个Java 字节码操作框架)
·基于接口的JDK动态代理
定义目标类,即被代理的类。
通过实现InvocationHandler接口来自定义自己的InvocationHandler;重写invoke方法,在此方法中定义增强逻辑。
通过Proxy.newProxyInstance方法获得代理对象。
通过代理对象调用目标方法;
·基于类的CGLIB动态代理		
。引入CGLIB的相关依赖。		
。定义目标类,即被代理的类。		
。创建代理类实现CGLIB的MethodInterceptor接口,并重写intercept方法,在此方法中定义增强逻
辑。	
。使用Enhancer类创建代理对象,设置目标类、回调对象等参数。
。调用代理对象的方法,实现代理行为

JDK Proxy与CGLIB的区别
.基于接口vs.基于类
JDK Proxy 只能代理接口类型,它通过实现指定接口并生成代理对象来实现代理功能。
CGLIB 可以代理普通的类,它通过继承目标类,并在子类中重写方法来实现代理。
.实现方式:
JDK Proxy 是基于反射机制实现的,它利用Java的反射API 动态生成代理对象。
CGLIB 使用了字节码生成库,直接操作字节码生成代理类。相比于JDK 代理的反射调用,CGLIB 的方法调用更快速。
.性能:
由于CGLIB是直接对字节码进行操作,所以在创建和执行代理对象时通常比JDK代理更快速。
JDK Proxy 的性能略低,因为它涉及到反射调用的开销。JDK8版本已经优化,性能与CGLIB差不多。
.库依赖:
JDK Proxy 是Java标准库的一部分,无需额外的依赖。 CGLIB 需要引入相关的第三方库。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值