Java函数式编程
函数式编程
从JDK1.8开始为了简化使用者进行代码的开发,专门提供有lambda表达式的支持,利用此操作形式可以实现函数式的编程,对于函数编程比较著名的语言是:haskell、Scala,利用函数式的编程可以避免掉面向对象编程过程中的一些繁琐的问题。
面向对象在其长期发展的过程中一直有一部分的反对者,这些反对者认为面向对象的设计过于复杂繁琐,以一个最简单的程序为例:
范例:观察传统开发中的问题
interface IMessage{
public void send(String str);
}
public class Main { public static void main(String[] args) {
IMessage msg=new IMessage() {
@Override
public void send(String str) {
System.out.println("消息发送:"+str);
}
};
msg.send("hello");
}
}
1,Lamda表达式在这个程序中,实际上核心的功能只有一行语句【System.out.println("消息发送:"+str);】,但是为了这样一行核心语句我们需要按照完整的面向对象给出的设计结构进行开发。于是这些问题随着技术的不断发展也是越来越突出。
范例:使用Lambda表达式实现上面相同的功能
interface IMessage{
public void send(String str);
}
public class Main { public static void main(String[] args) {
IMessage msg=(str)->{
System.out.println("消息发送:"+str);};
msg.send("hello");
}
}
Lambda表达式如果想要使用,那么必须有一个重要的实现要求:SAM(Single Abstract Method),只有一个抽象方法,在这个接口里面只是提供一个send()方法,除此之外没有任何其他方法定义,所以这样的接口就被定义为函数式接口,而只有函数式接口才能被Lambda表达式所使用。现在整个程序代码里面会发现真的只是编写了一行语句,于是利用这种形式就避免了复杂的面向对象结构化的要求。
范例:函数式接口里面的方法只能有一个
@FunctionalInterface//函数式接口
interface IMessage{//JDK1.8之后接口里面可以定义普通方法和Static方法
public void send(String str);
public default void print() {//这是一个
System.out.println("公共方法");
}
}
public class Main { public static void main(String[] args) {
IMessage msg=(str)->{
System.out.println("消息发送:"+str);};
msg.send("hello");
msg.print();
}
}
①方法没有参数:()->{}对于Lambda表达式而言,需要提供有如下几种格式:
②方法有参数:(参数,参数)->{}
③如果现在只有一行语句返回:(参数,参数)->语句;
范例:定义没有参数的方法
@FunctionalInterface//函数式接口
interface IMessage{//JDK1.8之后接口里面可以定义普通方法和Static方法
public void send();
}
public class Main {
public static void main(String[] args) {
IMessage msg=()->{
System.out.println("消息发送:这是个无参lambda形式");};
msg.send();
}
}
范例:定义有参数的
@FunctionalInterface//函数式接口
interface IMath{//JDK1.8之后接口里面可以定义普通方法和Static方法
public int add(int x,int y);
}
public class Main {
public static void main(String[] args) {
IMath math=(t1,t2)->{
return t1+t2;
};
System.out.println(math.add(10,20));
}
}
范例:简化Lambda操作以上表达式只有一行语句,这个时候也可以进一步简化。
@FunctionalInterface//函数式接口
interface IMath{//JDK1.8之后接口里面可以定义普通方法和Static方法
public int add(int x,int y);
}
public class Main {
public static void main(String[] args) {
IMath math=(t1,t2)->t1+t2;{
};
System.out.println(math.add(10,20));
}
}
利用lambda可以摆脱传统面向对象的关于结构的限制,使得代码更加的简便。只用于替换SAM的函数式接口
2,方法引用
引用数据类型最大的特点是可以进行内存的指向处理,但是在我们传统的开发之中一直所使用的只是对象的引用操作,从JDK1.8之后也有方法的引用,即不同的方法名称可以描述同一个方法。如果进行方法的引用在java里面提供有如下的四种形式。
①引用静态方法: 类名称::static 方法名称;
②引用某个实例对象的方法: 实例化对象::普通方法;
③引用特定类型的方法: 特定类::普通方法;
④引用构造方法: 类名称::new。
在String类里面提供有String.valueOf()方法,这个方法属于静态方法。
方法定义:public static String valueOf(int i),该方法有参数,并且有返回值;
·范例:
@FunctionalInterface//函数式接口
interface IFunction<P,R>{//P描述参数,R描述返回值
public R change(P p);
}
public class Main {
public static void main(String[] args) {
IFunction<Integer,String>fun=String::valueOf;
String str=fun.change(100);
System.out.println(str.length());
}
}
·范例:引用实例化对象中的方法利用方法引用这一概念可以为一个方法定义多个名字,但是要求必须是函数式接口。
在String类里面有一个转大写的方法:public String toUpperCase();
·这个方法是必须有实例化对象提供的情况下才可以调用;
@FunctionalInterface//函数式接口
interface IFunction<R>{//P描述参数,R描述返回值
public R upper();
}
public class Main {
public static void main(String[] args) {
IFunction<String>fun="hello"::toUpperCase;
String str=fun.upper();
System.out.println(str);
}
}
这是一个普通方法,如果要引用普通方法,则往往都需要实例化对象,但是如果说现在你不想给出实例化对象,只是想引用这个方法。则就可以使用特定类进行引用处理。在进行方法引用的时候也可以进行特定类的一些操作方法,在String类中提供一个字符串大写关系的比较: public int compareTo(String anotherString);
·范例:引用特定类中的方法
@FunctionalInterface//函数式接口
interface IFunction<P>{//P描述参数,R描述返回值
public int compare(P p1,P p2);
}
public class Main {
public static void main(String[] args) {
IFunction<String>fun=String::compareTo;
System.out.println(fun.compare("A","a"));
}
}
范例:引用构造方法在方法里面最具杀伤力的是构造方法的引用。
class Person{
private String name;
private int age;
public Person(String name,int age){
this.name=name;
this.age=age;
}
@Override
public String toString() {
return "姓名:"+this.name+",年龄:"+this.age;
}
}
@FunctionalInterface//函数式接口
interface IFunction<R>{//P描述参数,R描述返回值
public R create(String s,int a);
}
public class Main {
public static void main(String[] args) {
IFunction<Person>fun=Person::new;
System.out.println(fun.create("Wanyu",25));
}
}
提供方法引用的概念更多的情况下也只是弥补了对于引用的支持功能。
3,内建函数式接口
在JDK1.8之中提供Lambda表达式也提供方法引用,但是你会发现现在由开发者自己定义函数式接口往往需要使用【@FunctionInterface】注解来进行大量的声明,于是很多的情况下如果为了方便则可以引用系统中提供的函数式接口。
在系统值周专门提供有有一个java.util.function的开发包,里面可以直接使用函数式接口,在这个包下面可以直接使用如下的几个核心接口:
①功能性函数式接口:
·在String类中有一个方法判断是否以指定的字符串开头:public boolean startsWith(String str)
接口定义 |
接口使用 |
@FunctionalInterface public interface Function<T,R>{ public R apply(T t); } |
import java.util.function.*; |
②消费型函数式接口:只能进行数据处理操作
·在进行系统数据输出的时候使用的是:System.out.println()
接口定义 |
接口使用 |
@FunctionalInterface public interface Consumer<T>{ public void accept(T t); } |
import java.util.function.*; |
③供给型函数式接口:
·在String类中提供有转小写方法,这个方法没有接收参数,但是有返回值;
|-方法:public String toLowerCase();
接口定义 |
接口使用 |
@FunctionalInterface public interface Supplier<T>{ public T get(); } |
import java.util.function.*; |
④断言型函数式接口:进行判断处理
·在String类有一个compareToIgnoreCase()
接口定义 |
接口使用 |
@FunctionalInterface public interface Predicate<T>{ public boolean test(T t); } |
import java.util.function.*; |
以后对于实际开发之中,如果JDK本身提供的函数式接口可以被我们所使用,那么就没有必要重新定义了。
Java函数式编程的更多相关文章
- paip.提升效率---filter map reduce 的java 函数式编程实现
#paip.提升效率---filter map reduce 的java 函数式编程实现 ======================================================= ...
- 《深入理解Java函数式编程》系列文章
Introduction 本系列文将帮助你理解Java函数式编程的用法.原理. 本文受启发于JavaOne 2016关于Lambda表达式的相关主题演讲Lambdas and Functional P ...
- Java函数式编程原理以及应用
一. 函数式编程 Java8所有的新特性基本基于函数式编程的思想,函数式编程的带来,给Java注入了新鲜的活力. 下面来近距离观察一下函数式编程的几个特点: 函数可以作为变量.参数.返回值和数据类型. ...
- Java函数式编程:一、函数式接口,lambda表达式和方法引用
Java函数式编程 什么是函数式编程 通过整合现有代码来产生新的功能,而不是从零开始编写所有内容,由此我们会得到更加可靠的代码,并获得更高的效率 我们可以这样理解:面向对象编程抽象数据,函数式编程抽象 ...
- Java函数式编程:二、高阶函数,闭包,函数组合以及柯里化
承接上文:Java函数式编程:一.函数式接口,lambda表达式和方法引用 这次来聊聊函数式编程中其他的几个比较重要的概念和技术,从而使得我们能更深刻的掌握Java中的函数式编程. 本篇博客主要聊聊以 ...
- Java函数式编程:三、流与函数式编程
本文是Java函数式编程的最后一篇,承接上文: Java函数式编程:一.函数式接口,lambda表达式和方法引用 Java函数式编程:二.高阶函数,闭包,函数组合以及柯里化 前面都是概念和铺垫,主要讲 ...
- Java函数式编程和lambda表达式
为什么要使用函数式编程 函数式编程更多时候是一种编程的思维方式,是种方法论.函数式与命令式编程的区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉代码要怎么做.说白了,函数式编程是基于 ...
- 精练代码:一次Java函数式编程的重构之旅
摘要:通过一次并发处理数据集的Java代码重构之旅,展示函数式编程如何使得代码更加精练. 难度:中级 基础知识 在开始之前,了解"高阶函数"和"泛型"这两个概念 ...
- [译]通往 Java 函数式编程的捷径
原文地址:An easier path to functional programming in Java 原文作者:Venkat Subramaniam 译文出自:掘金翻译计划 以声明式的思想在你的 ...
- Java 函数式编程(Lambda表达式)与Stream API
1 函数式编程 函数式编程(Functional Programming)是编程范式的一种.最常见的编程范式是命令式编程(Impera Programming),比如面向过程.面向对象编程都属于命令式 ...
随机推荐
- ajax下post提交方式下载文件的处理(转)
ajax是不能直接下载文件的,所以一般都是通过一个超链接的形式去下载一个文件 但是当牵扯到需要发送很多数据到服务器上再下载的时候超链接的形式就有些不好看了, /*=================== ...
- CentOS里下载和离线安装rpm包
离线下载rpm包 yum --downloadonly --downloaddir=/home/packages install mariadb-devel 安装离线rpm包 进入下载包的 ...
- 使用kubectl访问kubernetes集群
之前访问k8s都是通过token进去dashboard,如下所示.但是现在希望通过kubectl访问k8s,所以还需要进一步的配置. 1. 安装kubectl命令行工具,配置环境变量,环境变量的值指向 ...
- ubuntu之路——day20 昨天和今天搞定Res18并在GPU上运行 明天YOLO在车辆识别上试一下
- Cesium 1.54评测 【转】
重要功能评测 3dtiles数据上画线和贴纹理 3dtiles数据上画线和贴纹理 把线条贴到3dtiles上需要用到两个属性:clampToGround和classificationType. c ...
- Server Tomcat v8.5 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
Server Tomcat v9.0 Server at localhost was unable to start within 45 seconds. If the server requires ...
- dashi 成长 > 领导 > 平台 > 钱 人品 态度 能力 价值
https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=thy3557s https://www.aliyun.com/min ...
- electron---更改安装图标
在用electron开发桌面端的时候,打包成exe文件,需要更改默认的图标: 具体做法: 在根目录新建新建存放icon图标的目录: 需要两个icon:icon.icns,icon.ico 注意: 1. ...
- some try on func swap about & and *
import "fmt" func swap(x,y *int ) { //x ,y = y,x //fault /* t := *x *x = *y *y = t */ //tr ...
- server computer (实验室移动服务器环境)
star@xmatrix:~$ lshwWARNING: you should run this program as super-user.xmatrix ...