3分钟看完Java 8——史上最强Java 8新特性总结之第三篇 函数式编程技巧
目录
· 改写设计模式
· 模板方法模式(Template Method Pattern)
· 责任链模式(Chain of Responsibility Pattern)
· 简单工厂模式(Simple Factory Pattern)
· 高阶函数与柯里化
改写设计模式
策略模式(Strategy Pattern)
1. 改写前
a) ValidationStrategy.java
public interface ValidationStrategy {
boolean execute(String s);
}
b) IsNumeric.java
public class IsNumeric implements ValidationStrategy {
public boolean execute(String s) {
return s.matches("\\d+");
}
}
c) IsAllLowerCase.java
public class IsAllLowerCase implements ValidationStrategy {
public boolean execute(String s) {
return s.matches("[a-z]+");
}
}
d) Validator.java
public class Validator {
private final ValidationStrategy strategy;
public Validator(ValidationStrategy v) {
this.strategy = v;
}
public boolean validate(String s) {
return strategy.execute(s);
}
}
e) Test.java
public class Test {
public static void main(String[] args) {
Validator numericValidator = new Validator(new IsNumeric());
boolean b1 = numericValidator.validate("aaaa");
System.out.println(b1); // false
Validator lowerCaseValidator = new Validator(new IsAllLowerCase());
boolean b2 = lowerCaseValidator.validate("bbbb");
System.out.println(b2); // true
}
}
2.改写后
a) Test.java
public class Test {
public static void main(String[] args) {
Validator numericValidator = new Validator((String s) -> s.matches("\\d+"));
boolean b1 = numericValidator.validate("aaaa");
System.out.println(b1); // false
Validator lowerCaseValidator = new Validator(s -> s.matches("[a-z]+"));
boolean b2 = lowerCaseValidator.validate("bbbb");
System.out.println(b2); // true
}
}
模板方法模式(Template Method Pattern)
1. 改写前
a) Customer.java
public class Customer {
private int id;
private String name;
public Customer(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
b) OnlineBanking.java
public abstract class OnlineBanking {
public void processCustomer(int id) {
Customer c = new Customer(id, "Jhon");
makeCustomerHappy(c);
}
abstract void makeCustomerHappy(Customer c);
}
2.改写后
a) OnlineBankingLambda.java
import java.util.function.Consumer;
public class OnlineBankingLambda {
public void processCustomer(int id, Consumer<Customer> makeCustomerHappy) {
Customer c = new Customer(id, "Jhon");
makeCustomerHappy.accept(c);
}
}
b) Test.java
public class Test {
public static void main(String[] args) {
new OnlineBankingLambda().processCustomer(1337, (Customer c) -> System.out.println("Hello " + c.getName()));
}
}
观察者模式(Observer Pattern)
1. 改写前
a) Observer.java
public interface Observer {
void notify(String tweet);
}
b) NYTimes.java
public class NYTimes implements Observer {
public void notify(String tweet) {
if (tweet != null && tweet.contains("money")) {
System.out.println("Breaking news in NY! " + tweet);
}
}
}
c) Guardian.java
public class Guardian implements Observer {
public void notify(String tweet) {
if (tweet != null && tweet.contains("queen")) {
System.out.println("Yet another news in London... " + tweet);
}
}
}
d) LeMonde.java
public class LeMonde implements Observer {
public void notify(String tweet) {
if (tweet != null && tweet.contains("wine")) {
System.out.println("Today cheese, wine and news! " + tweet);
}
}
}
e) Subject.java
public interface Subject {
void registerObserver(Observer o);
void notifyObservers(String tweet);
}
f) Feed.java
public class Feed implements Subject {
private final List<Observer> observers = new ArrayList<>();
public void registerObserver(Observer o) {
this.observers.add(o);
}
public void notifyObservers(String tweet) {
observers.forEach(o -> o.notify(tweet));
}
}
g) Test.java
public class Test {
public static void main(String[] args) {
Feed f = new Feed();
f.registerObserver(new NYTimes());
f.registerObserver(new Guardian());
f.registerObserver(new LeMonde());
f.notifyObservers("The queen said her favourite book is Java 8 in Action!");
}
}
2.改写后
a) Test.java
public class Test {
public static void main(String[] args) {
Feed f = new Feed();
f.registerObserver((String tweet) -> {
if (tweet != null && tweet.contains("money")) {
System.out.println("Breaking news in NY! " + tweet);
}
});
f.registerObserver((tweet) -> {
if (tweet != null && tweet.contains("queen")) {
System.out.println("Yet another news in London... " + tweet);
}
});
f.registerObserver((tweet) -> {
if (tweet != null && tweet.contains("wine")) {
System.out.println("Today cheese, wine and news! " + tweet);
}
});
f.notifyObservers("The queen said her favourite book is Java 8 in Action!");
}
}
责任链模式(Chain of Responsibility Pattern)
1. 改写前
a) ProcessingObject.java
public abstract class ProcessingObject<T> {
protected ProcessingObject<T> successor;
public void setSuccessor(ProcessingObject<T> successor) {
this.successor = successor;
}
public T handle(T input) {
T r = handleWork(input);
if (successor != null) {
return successor.handle(r);
}
return r;
}
protected abstract T handleWork(T input);
}
b) HeaderTextProcessing.java
public class HeaderTextProcessing extends ProcessingObject<String> {
public String handleWork(String text) {
return "From Raoul, Mario and Alan: " + text;
}
}
c) SpellCheckerProcessing.java
public class SpellCheckerProcessing extends ProcessingObject<String> {
public String handleWork(String text) {
return text.replaceAll("labda", "lambda");
}
}
d) Test.java
public class Test {
public static void main(String[] args) {
ProcessingObject<String> p1 = new HeaderTextProcessing();
ProcessingObject<String> p2 = new SpellCheckerProcessing();
p1.setSuccessor(p2);
String result = p1.handle("Aren't labdas really sexy?!!");
System.out.println(result);
}
}
2.改写后
a) Test.java
public class Test {
public static void main(String[] args) {
UnaryOperator<String> headerProcessing = (String text) -> "From Raoul, Mario and Alan: " + text;
UnaryOperator<String> spellCheckerProcessing = (String text) -> text.replaceAll("labda", "lambda");
Function<String, String> pipeline = headerProcessing.andThen(spellCheckerProcessing);
String result = pipeline.apply("Aren't labdas really sexy?!!");
System.out.println(result);
}
}
简单工厂模式(Simple Factory Pattern)
1. 改写前
a) Product.java
public interface Product {
}
b) Loan.java
public class Loan implements Product {
}
c) Stock.java
public class Stock implements Product {
}
d) Bond.java
public class Bond implements Product {
}
e) ProductFactory.java
public class ProductFactory {
public static Product createProduct(String name) {
switch (name) {
case "loan":
return new Loan();
case "stock":
return new Stock();
case "bond":
return new Bond();
default:
throw new RuntimeException("No such product " + name);
}
}
}
f) Test.java
public class Test {
public static void main(String[] args) {
Product p = ProductFactory.createProduct("loan");
}
}
2. 改写后
a) ProductFactory.java
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier; public class ProductFactory { final static Map<String, Supplier<Product>> map = new HashMap<>(); static {
map.put("loan", Loan::new);
map.put("stock", Stock::new);
map.put("bond", Bond::new);
} public static Product createProduct(String name) {
Supplier<Product> p = map.get(name);
if (p != null) return p.get();
throw new IllegalArgumentException("No such product " + name);
} }
b) Test.java
public class Test {
public static void main(String[] args) {
Product p = ProductFactory.createProduct("loan");
}
}
高阶函数与柯里化
1. 高阶函数(Higher-order Function):满足以下任意一个条件都是高阶函数。
a) 接受至少一个函数作为参数。
b) 返回的结果是一个函数。
2. 柯里化(Currying):假设有一个函数 f(x, y) ,柯里化就是把多个参数的函数f转化为一个参数的函数g,并且函数g的返回值一个新函数,即 f(x, y) = (g(x))(y) 。
3. 柯里化好处:灵活、复用。
4. 举例
a) 柯里化前
public class Test {
public static double converter(double x, double f, double b) {
return x * f + b;
}
public static void main(String[] args) {
double gbp = converter(1000, 0.6, 0);
System.out.println(gbp);
}
}
b) 柯里化后
public class Test {
public static DoubleUnaryOperator curriedConverter(double f, double b) {
return (double x) -> x * f + b;
}
public static void main(String[] args) {
DoubleUnaryOperator convertCtoF = curriedConverter(9.0 / 5, 32);
DoubleUnaryOperator convertUSDtoGBP = curriedConverter(0.6, 0);
DoubleUnaryOperator convertKmtoMi = curriedConverter(0.6214, 0);
double gbp = convertUSDtoGBP.applyAsDouble(1000);
System.out.println(gbp);
}
}
作者:netoxi
出处:http://www.cnblogs.com/netoxi
本文版权归作者和博客园共有,欢迎转载,未经同意须保留此段声明,且在文章页面明显位置给出原文连接。欢迎指正与交流。
3分钟看完Java 8——史上最强Java 8新特性总结之第三篇 函数式编程技巧的更多相关文章
- 3分钟看完Java 8——史上最强Java 8新特性总结之第二篇 Stream API
目录 · 概况 · 切片(Slicing) · 映射(Mapping) · 匹配(Matching) · 查找(Finding) · 归约(Reducing) · 排序(Sorting) · 数值流( ...
- 3分钟看完Java 8——史上最强Java 8新特性总结之第一篇 函数式编程基础
目录 · 行为参数化 · Lambda表达式 · 概况 · 函数式接口 · 类型推断 · 使用外层变量 · 方法引用 · 复合Lambda表达式 行为参数化 1. 理解函数式编程要先理解行为参数化. ...
- 3分钟看完Java 8——史上最强Java 8新特性总结之第四篇 其他新特性
目录 · 默认方法和静态方法 · 初步理解 · 应用模式 · 优先级问题 · Optional · CompletableFuture · 基本用法 · CompletableFuture与Strea ...
- 史上最强Java NIO入门:担心从入门到放弃的,请读这篇!
本文原题“<NIO 入门>,作者为“Gregory M. Travis”,他是<JDK 1.4 Tutorial>等书籍的作者. 1.引言 Java NIO是Java 1.4版 ...
- 金九银十,史上最强 Java 面试题整理。
以下会重新整理所有 Java 系列面试题答案.及各大互联网公司的面试经验,会从以下几个方面汇总,本文会长期更新. Java 面试篇 史上最全 Java 面试题,带全部答案 史上最全 69 道 Spri ...
- 史上最强Java开发环境搭建
在项目产品开发中,开发环境搭建是软件开发的首要阶段,也是必须阶段,只有开发环境搭建好了,方可进行开发,良好的开发环境搭建,为后续的开发工作带来极大便利. 对于大公司来说,软件开发环境搭建工作一般是由运 ...
- Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码
美国时间 09 月 25 日,Oralce 正式发布了 Java 11,这是据 Java 8 以后支持的首个长期版本. 为什么说是长期版本,看下面的官方发布的支持路线图表. 可以看出 Java 8 扩 ...
- c#代码 天气接口 一分钟搞懂你的博客为什么没人看 看完python这段爬虫代码,java流泪了c#沉默了 图片二进制转换与存入数据库相关 C#7.0--引用返回值和引用局部变量 JS直接调用C#后台方法(ajax调用) Linq To Json SqlServer 递归查询
天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找到合适天气预报接口一切都是小意思,说干就干,立马跟学生沟通价格. 不过谈报价的过程中,差点没让我一口老血喷键盘上,话说我们程序猿的人 ...
- 一文深入了解史上最强的Java堆内缓存框架Caffeine
它提供了一个近乎最佳的命中率.从性能上秒杀其他一堆进程内缓存框架,Spring5更是为了它放弃了使用多年的GuavaCache 缓存,在我们的日常开发中用的非常多,是我们应对各种性能问题支持高并发的一 ...
随机推荐
- BZOJ4380 Myjnie / Luogu3592 [POI2015]MYJ-区间DP
Description 有$n$家洗车店从左往右排成一排,每家店都有一个正整数价格$p[i]$. 有$m$个人要来消费,第$i$个人会驶过第$a[i]$个开始一直到第$b[i]$个洗车店,且会选择这些 ...
- BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan
Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...
- mysql启动错误,提示crash 错误
:: mysqld_safe Starting mysqld daemon with databases from /data/mysql_data -- :: [Note] Plugin 'FEDE ...
- linux debian 9 / centos 7配置postgresSQL数据库
#读者注意:本文可以选择不看解释,直接执行每段的0中的代码 (〇):一些概念(可以跳过直接使用(一)0的代码) 1. 客户端:psql.postgreSQL的命令行客户端程序,在终端输入psql进入p ...
- epoll_wait会被系统中断唤醒
今天,当一个程序在epoll_wait阻塞时,用strace跟踪了一下,结果epoll_wait就被EINTR唤醒了,并且返回-1: 所以,当epoll_wait返回-1时,需要判断errno是不是E ...
- 目录命令(cd)
cd 命令: // 描述: (Change Directory) 更改当前目录或显示当前目录的名称. 如果仅使用驱动器号(例如,cd C :),则cd将显示指定驱动器中当前目录的名称. 如果不带参数使 ...
- CCPC-2017-秦皇岛站
10月25日 听说信用卡到了好兴奋,然而没有额度是啥情况啊qwq. 晚上坐飞机出发,成都-鄂尔多斯-石家庄-秦皇岛,队友吐槽鄂尔多斯到石家庄好近啊,然后过了一会儿我们因为石家庄大雾迫降在了济南.嘤嘤嘤 ...
- 18.数组(一)之认识java数组
数组是一个简单的复合数据类型,它是一组有序数据的集合,它当中的每一个数据都具有相同的数据类型,我们通过数组名再加上一个不会越界的下标值来唯一确定数组中的元素. 还有就是,数组是一个特殊的对象. 不管在 ...
- 杂七杂八的JavaScript
一.input 焦点定位 1.定位input:(this.$refs.searchInput as HTMLInputElement).focus(); 2.定位search,根据css选择器: ...
- 嵌入式小系统I2S接口调试总结
最近调试了I2S.由于芯片里面硬件配置出现了几个错误,着实也把我折腾了一番,不过,最终 还是把它搞定了.为了加深理解,就做个笔记吧,方面以后查找和学习. 定义:I²S或I2S(英语:Inter-IC ...