java利刃_JAVA基础(五)函数式接口-复用,解耦之利刃

61e81deef0da713a588348915bf64ba9.png

Java极客  |  作者  /  铿然一叶

这是Java极客的第 67 篇原创文章

相关阅读:

JAVA基础(一)简单、透彻理解内部类和静态内部类

JAVA基础(二)内存优化-使用Java引用做缓存

JAVA基础(三)ClassLoader实现热加载

JAVA基础(四)枚举(enum)和常量定义,工厂类使用对比

JAVA编程思想(一)通过依赖注入增加扩展性

JAVA编程思想(二)如何面向接口编程

JAVA编程思想(三)去掉别扭的if,自注册策略模式优雅满足开闭原则

JAVA编程思想(四)Builder模式经典范式以及和工厂模式如何选?

HikariPool源码(二)设计思想借鉴

人在职场(一)IT大厂生存法则

1. 函数式接口

接口中只有一个抽象方法的接口称为函数式接口。函数式接口可以通过@FunctionalInterface注解来修饰,也可以不使用该注解,只要接口只有一个抽象方法则可。

2. 函数式接口使用例子

2.1. 服务和消费者

import java.util.function.Consumer;

public class Service {

// 方法入参为函数式接口,函数定义为消费Event

public void exec(Consumer consumer) {

Event event = new Event(1001, "get data from cache.");

consumer.accept(event);

}

}

// event通知消费类,消费event的方式是将event发出去

public class EventNotify {

// 方法名并不重要,不需要和函数式接口方法名一致,只要参数和返回值一致则可

public void send(Event event) {

System.out.println("send event: " + event.toString());

}

}

// event记录消费类,消费event的方式是将event记录下来

public class EventLogger {

// 方法名并不重要,不需要和函数式接口方法名一致,只要参数和返回值一致则可

public static void log(Event event) {

System.out.println("log event: " + event.toString());

}

}

public class Event {

private int eventId;

private String content;

public Event(int eventId, String content) {

this.eventId = eventId;

this.content = content;

}

@Override

public String toString() {

StringBuilder builder = new StringBuilder();

builder.append("eventId=").append(eventId).append(", ");

builder.append("content=").append(content);

return builder.toString();

}

}

复制代码

2.2. 使用函数式接口

public class FunctionDemo {

public static void main(String[] args) {

Service service = new Service();

EventNotify eventNotify = new EventNotify();

// 使用类实例::方法名传入函数,这里必须使用类实例,是因为这个方法声明为非静态方法

service.exec(eventNotify::send);

// 使用类::方法名传入函数,这里可以使用类而非类实例,是因为这个方法声明为静态方法

service.exec(EventLogger::log);

}

}

复制代码

输出:

send event: eventId=1001, content=get data from cache.

log event: eventId=1001, content=get data from cache.

复制代码

看到这里,很多人会想,从这个例子看,函数式接口并没有什么优势,不用函数式接口,使用接口实现类也能实现啊.

2.3. 不用函数式接口实现例子

2.3.1. 消费者直接实现接口方法

class NonFunctionEventNotify implements Consumer {

@Override

public void accept(Event event) {

System.out.println("send event: " + event.toString());

}

}

// 事件记录类,消费event的方式是将event记录下来

class NonFunctionEventLogger implements Consumer {

@Override

public void accept(Event event) {

System.out.println("log event: " + event.toString());

}

}

复制代码

2.3.2. 使用接口实现类

public class FunctionDemo {

public static void main(String[] args) {

Service service = new Service();

NonFunctionEventNotify nonFunctionEventNotify = new NonFunctionEventNotify();

// 传入实现类实例

service.exec(nonFunctionEventNotify);

NonFunctionEventLogger nonFunctionEventLogger = new NonFunctionEventLogger();

// 传入实现类实例

service.exec(nonFunctionEventLogger);

}

}

复制代码

可见,不用函数式接口也能实现对应功能,那为啥还要使用函数式接口呢?

2.3.2. 函数式接口和接口实现方式差异以及优点

差异如下:

实现方式

掺入参数

实现接口

方法名

函数式接口

可直接传入静态方法,省去类实例化动作

不需要实现任何接口

没有要求,只要方法入参和出参一样则可

接口实现类

必须有类实例,传入类实例

需要实现指定接口

必须同接口方法完全一样

通过对比,函数式接口的优势就大大体现出来了。

方法入参到方法级,粒度比类小,这样自由度更高,更灵活,就好比拼乐高,零件粒度越小,越能充分发挥想象力,进行自由组合。

不要求必须实现某个接口,对方法名也没有要求,只要满足函数接口的入参和出参定义就行,这样已有的代码可能不用修改就能被利用,特别是当你手里没有源码可改时这点显得尤为重要(虽然可以写个包装类去做适配,但能不写不是更好么)

3. 总结

函数式接口可以做到方法级复用,自由度更高,更灵活

函数式接口的方法定义和调用者实现方法定义解耦,不需要方法一致,也不要求实现该接口。

方法定义解耦后,只要方法的入参和出参一致时,就可以复用已有代码,避免修改,复用性大大提高。

注:Java提供的函数式接口已经能满足大部分使用场景,这些接口可以在java.util.function包下找到。

end.

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[JAVA基础(五)函数式接口-复用,解耦之利刃]http://www.zyiz.net/tech/detail-132761.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值