函数式方法的实现(JDK8+)

1、使用场景

例:在业务中难免会有对象嵌套的情况,下面就是模拟对象属性嵌套对象的一个简单Demo,在真实场景中,肯定会有复杂嵌套。我就以下面简单的Demo为例,来讲述函数式方法的实现。

在methodA()和methodB()两个方法中存在着相同的校验,而且最终对目标的处理逻辑却不同,此时按照常规的解决办法肯定是将两个方法中相同的校验部分提取成公共的方法,然后在两个方法中在进行调用,若经过的了校验才在每个方法中执行各自不同的逻辑。

但是,这里有一个问题,若提取了公共校验方法并接受A的对象为参数,那么在校验方法中肯定是需要一层一层的解出来嵌套的对象E并进行校验。然后在methodA()和methodB()方法中肯定会先调用校验方法并传递对象a,经过校验之后再对对象E的属性进行操作。此时问题来了,此时在methodA()和methodB()方法中是没有对A对象进行一层一层的解出来E对象的,所以也就是说当经过校验之后,还需要在各自的方法里在进行一次解剖的操作,此时不就代码不又重复了吗?你可能会想,下面这个直接使用a.getB().getC().getD().getE()一行代码不就拿到了E对象了吗?在下面这个Demo中是这样的,但是若嵌套的对象中包含集合和单实例对象混合呢或者其他更加复杂的嵌套呢,这样的话一行就解决不了了。于是,在这个场景下,我们应该使用公共的函数式方法,也就是将methodA()和methodB()两个方法中各自的处理逻辑提取成一个函数式接口作为公共方法的参数传递,这样的话解剖的过程被提取出来了,然后具体的处理逻辑也以调用处传递的匿名内部类的处理逻辑为准,于是就解决了这个问题,并提高了复用性。

java 复制代码
@Slf4j
public class Test1 {
    public static void main(String[] args) {
        methodA();
        methodB();
    }

    private static void methodA() {
        A a = new A(new B(new C(new D(new E("Y", 24)))));
        B b = a.getB();
        if (b == null){
            return;
        }
        C c = b.getC();
        if (c == null){
            return;
        }
        D d = c.getD();
        if (d == null){
            return;
        }
        E e = d.getE();
        if (e == null){
            return;
        }
        if ("Y".equals(e.getName())){
            e.setAge(20);
        }
        log.info("methodA方法:" + e);
    }

    private static void methodB() {
        A a = new A(new B(new C(new D(new E("Y", 18)))));
        B b = a.getB();
        if (b == null){
            return;
        }
        C c = b.getC();
        if (c == null){
            return;
        }
        D d = c.getD();
        if (d == null){
            return;
        }
        E e = d.getE();
        if (e == null){
            return;
        }
        processString(a, e -> {
            if (18 == e.getAge()){
                e.setName("N");
            }
        });
        log.info("methodB方法:" + e);
    }
}

@Data
@AllArgsConstructor
class A{
    private B b;
}

@Data
@AllArgsConstructor
class B{
    private C c;
}

@Data
@AllArgsConstructor
class C{
    private D d;
}

@Data
@AllArgsConstructor
class D{
    private E e;
}

@Data
@AllArgsConstructor
class E{
    private String name;
    private Integer age;
}

2、结合 java.util.function 包下的Consumer接口实现函数式方法

Java 在 java.util.function 包中提供了许多内置的函数式接口,**Consumer<T>就是其中一个,它接受一个输入参数,然后无返回结果。上述Demo即可结合Consumer<T>**实现函数式方法的提取。

在下面的代码中实现了一个processString方法,该方法接收两个参数,第一个参数是A对象,第二个参数是Consumer 接口。泛型的类型是在processString方法中最终要对谁进行处理,也就是 accept接口的入参类型,然后在methodA()和methodB()方法中通过匿名内部类的方式传递需要处理的逻辑。

java 复制代码
@Slf4j
public class Test1 {
    public static void main(String[] args) {
        methodA();
        methodB();
    }

    private static void methodA() {
        A a = new A(new B(new C(new D(new E("Y", 18)))));
        processString(a, e -> {
            if ("Y".equals(e.getName())){
                e.setAge(20);
            }
        });
        log.info("methodA方法:" + a.getB().getC().getD().getE());
    }

    private static void methodB() {
        A a = new A(new B(new C(new D(new E("Y", 18)))));
        processString(a, e -> {
            if (18 == e.getAge()){
                e.setName("N");
            }
        });
        log.info("methodB方法:" + a.getB().getC().getD().getE());
    }

    private static void processString(A a, Consumer<E> strProcessor) {
        B b = a.getB();
        if (b == null){
            return;
        }
        C c = b.getC();
        if (c == null){
            return;
        }
        D d = c.getD();
        if (d == null){
            return;
        }
        E e = d.getE();
        if (e == null){
            return;
        }
        // 执行接收到的不同处理逻辑
        strProcessor.accept(e);
    }
}

3、java.util.function 包中其他的函数式接口

  • Function<T,R>: 接受一个输入参数,返回一个结果
  • Predicate<T>: 接受一个输入参数,返回布尔值
  • Consumer<T>: 接受一个输入参数,无返回结果
  • Supplier<T>: 无输入参数,返回一个结果
  • BiFunction<T,U,R>: 接受两个输入参数,返回一个结果

还在测试中。。。详细使用会在后续更新!

文章内容若存在错误或需改进的地方,欢迎大家指正!非常感谢!

相关推荐
xinxiyinhe几秒前
内存泄漏与OOM崩溃根治方案:JVM与原生内存池差异化排查手册
java·开发语言·jvm
水水沝淼㵘几秒前
嵌入式开发学习日志(数据结构--顺序结构单链表)Day19
linux·服务器·c语言·数据结构·学习·算法·排序算法
心向阳光的天域4 分钟前
黑马Java跟学.最新AI+若依框架项目开发(一)
java
愚润求学8 分钟前
【Linux】基础 IO(一)
linux·运维·服务器·开发语言·c++·笔记
what_20189 分钟前
分布式链路跟踪
java·运维·分布式
oliveira-time17 分钟前
ArrayList和LinkedList区别
java·开发语言
潮流coder20 分钟前
IntelliJ IDEA给Controller、Service、Mapper不同文件设置不同的文件头注释模板、Velocity模板引擎
java·ide·intellij-idea
码农飞哥26 分钟前
互联网大厂Java求职面试实战:Spring Boot与微服务场景深度解析
java·数据库·spring boot·安全·微服务·消息队列·互联网医疗
Akiiiira43 分钟前
【日撸 Java 300行】Day 14(栈)
java·开发语言
猴子请来的逗比4891 小时前
tomcat与nginx之间实现多级代理
java·nginx·tomcat