函数式编程
什么是函数式编程
1·概念:
面向对象思想需要关注用什么对象完成什么事情。
而函数式编程思想就类似于我们数学中的函数,它主要关注的是对数据进行了什么操作。
2·优点:
• 代码简洁,开发快速</b>
• 接近自然语言,易于理解</b>
• 易于“并发编程”</b>
Lambda表达式
小实现
package lambda3;
/**
* @program: src
* @description: 定义一个计算接口,只有一个方法add
* @author: SongZhiZe
* @create: 2022-10-23 12:51
**/
public class Program {
// 定义接口-规范
interface Cal{
int add(int a,int b);
}
public static void main(String[] args) {
// 实现类-实现操作
/*
没有用Lambda实现的匿名内部类
Cal c = new Cal(){
// 方法实现
@Override
public int add(int a, int b) {
return a+b;
}
};
*/
Cal c = (int a,int b)->{
return a+b;
};
System.out.println(c.add(1, 2));
}
}
概述
Lambda是JDK8中一个语法糖。可以看成一种语法糖,他可以对某些匿名内部类的写法进行简化。它是函数式编程思想的一个重要体现。然我们不用关注是什么对象。而是更加关注我们对数据进行了什么操作,使用它设计的代码会更加简洁,通过Lambda表达式,可以替代我们以前常用的匿名内部类来实现接口。 Lambda表达式的本质就是一个匿名函数;
表达式语法
我们看下这个Lambda表达式: (int a,int b)->{return a+b;};
本质是一个函数 一般的函数类:int add (int a,int b){
return a+b;
}
有返回值,有方法名,参数列表,方法体
Lambda表达式函数的话,只有参数列表和方法体;
(参数列表)->{方法体}说明:
- ()用来描述参数列表;
- {}用来描述方法体;
- -> Lambda运算符,可以叫做箭头符号,或者goes to
Lambda表达式语法精讲
我们通过一个案例,接口方法参数,无参,单个参数,两个参数,没有返回值,这六种情况来了解Lambda表达式
package lambda3;
/**
* @program: src
* @description: 语法精讲
* @create: 2022-10-23 13:21
**/
public class Program1 {
/*无参数无返回值*/
interface IF1 {
void test();
}
/*单个参数无返回值*/
interface IF2 {
void test(int a);
}
/*两个参数无返回值*/
interface IF3 {
void test(int a, int b);
}
/*无参数有返回值*/
interface IF4 {
int test();
}
/*单个参数有返回值*/
interface IF5 {
int test(int a);
}
/*多个参数有返回值*/
interface IF6 {
int test(int a, int b);
}
public static void main(String[] args) {
IF1 if1 = () -> {
System.out.println("无参数无返回值");
};
// 调用方法
if1.test();
System.out.println("----------------------");
IF2 if2 = (int a) -> {
System.out.println("单个参数无返回值 a=" + a);
};
if2.test(3);
System.out.println("----------------------");
IF3 if3 = (int a, int b) -> {
System.out.println("两个参数无返回值 a+b=" + (a + b));
};
if3.test(12, 10);
System.out.println("----------------------");
IF4 if4=()->{
return 4;
};
System.out.println("无参数有返回值 "+if4.test());
System.out.println("----------------------");
IF5 if5=(int a)->{
return a;
};
System.out.println("单个参数有返回值 "+if5.test(5));
System.out.println("----------------------");
IF6 if6=(int a,int b)->{
return a*b;
};
System.out.println("两个参数有返回值 "+if6.test(10,20));
}
}
Lambda表达式精简语法
注意:
- 参数类型可以省略
- 假如只有一个参数,()可以省略
- 如果方法体只有一条语句,{}可以省略
- 如果方法体中唯一的语句是return返回语句,那省略大括号的同时return也要省略
实例改写:
package lambda3;
/**
* @program: src
* @description: 精简语法
* @create: 2022-10-23 13:21
**/
public class Program2 {
/*无参数无返回值*/
interface IF1 {
void test();
}
/*单个参数无返回值*/
interface IF2 {
void test(int a);
}
/*两个参数无返回值*/
interface IF3 {
void test(int a, int b);
}
/*无参数有返回值*/
interface IF4 {
int test();
}
/*单个参数有返回值*/
interface IF5 {
int test(int a);
}
/*多个参数有返回值*/
interface IF6 {
int test(int a, int b);
}
public static void main(String[] args) {
// 方法体只有一条语句,{}可以省略
IF1 if1 = () -> System.out.println("无参数无返回值");
// 调用方法
if1.test();
System.out.println("----------------------");
// 参数类型省略,一个参数,小括号省略,一条语句{}省略
IF2 if2 = a -> System.out.println("单个参数无返回值 a=" + a);
if2.test(3);
System.out.println("----------------------");
IF3 if3 = ( a, b) -> System.out.println("两个参数无返回值 a+b=" + (a + b));
if3.test(12, 10);
System.out.println("----------------------");
IF4 if4=()->4;
System.out.println("无参数有返回值 "+if4.test());
System.out.println("----------------------");
// 一个参数,小括号省略
IF5 if5= a ->a;
System.out.println("单个参数有返回值 "+if5.test(5));
System.out.println("----------------------");
IF6 if6=( a, b)->a*b;
System.out.println("两个参数有返回值 "+if6.test(10,20));
}
}
方法引用
有时候多个lambda表达式实现函数是一样的话,我们可以封装成通用方法,从而有利于维护;
这时候可以用方法引用实现: 语法是:对象::方法 假如是static方法,可以直接 类名: :方法实例如下
package lambda3;
/**
* @program: src
* @description: 方法引用
* @author: SongZhiZe
* @create: 2022-10-23 13:21
**/
public class Program3 {
/*单个参数有返回值*/
interface IF5 {
int test(int a);
}
/*非静态方法*/
public int testA(int a){
return a-2;
}
/*静态方法*/
public static int testB(int a){
return --a;
}
public static void main(String[] args) {
/* 非静态方法
Program3 program3 = new Program3();
IF5 if5 = program3::testA;
System.out.println(if5.test(3));
IF5 if51 =program3::testA;
System.out.println(if51.test(5));
*/
// 静态方法
IF5 if5 = Program3::testB;
System.out.println(if5.test(3));
IF5 if51 =Program3::testB;
System.out.println(if51.test(5));
/*
IF5 if5= a-> a-2;
System.out.println(if5.test(3));
IF5 if51=a-> a-2;
System.out.println(if5.test(5));
*/
}
}
Lambda表达式的实际应用
package lambda3.example;
/**
* @program: src
* @description: 定义的Dog实体类
* @create: 2022-10-23 22:06
**/
public class Dog {
private String name;
private int age;
public Dog(){
System.out.println("无参构造方法");
}
public Dog(String name, int age) {
System.out.println("有参构造方法");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package lambda3.example;
/**
* @program: src
* @description:
* @create: 2022-10-23 13:21
**/
public class Program4 {
// 定义两个接口
interface DogService{
Dog getDog();
}
interface DogService2{
Dog getDog(String name,int age);
}
public static void main(String[] args) {
/* DogService dogService=()-> new Dog();
// 无名无姓的dog
System.out.println(dogService.getDog());*/
DogService dogService= Dog::new;
// 无名无姓的dog
System.out.println(dogService.getDog());
DogService2 dogService2= Dog::new;
// 无名无姓的dog
System.out.println(dogService2.getDog("王吧",3));
}
}
通过Lambda表达式对新增的dog进行排序问题
package lambda3.example;
import java.util.ArrayList;
import java.util.function.Consumer;
/**
* @program: src
* @description: 综合案例
* @author: SongZhiZe
* @create: 2022-10-23 22:21
**/
public class Program5 {
public static void main(String[] args) {
ArrayList<Dog> list = new ArrayList<>();
list.add(new Dog("a", 1));
list.add(new Dog("b", 5));
list.add(new Dog("c", 4));
list.add(new Dog("d", 3));
list.add(new Dog("e", 2));
System.out.println("lambda表达式集合排序");
list.sort((o1, o2) -> o1.getAge() - o2.getAge());
System.out.println("lambda表达式遍历集合");
/* 下面是三种相同的遍历方法 */
// list.forEach(System.out::println);
/* list.forEach(
x->{
System.out.println(x);
}
);*/
list.forEach(
new Consumer<Dog>() {
@Override
public void accept(Dog x) {
System.out.println(x);
}
}
);
}
}
@FunctionalInterface 注解
在前面我们会发现Comsumer接口,Comparator接口都有@FunctionalInterface注解:
这个注解是函数式接口注解,所谓的函数式接口,首先是一个接口,然后在这个接口里面只有一个抽象方法。这种类型的接口也称之为SAM接口,即Single Abstract Method interfaces特点
- 接口有且仅有一个抽象方法
- 允许定义静态方法
- 允许定义默认方法
- 允许java.lang.Object中的public方法
- 该注解不是必须的,如果一个接口符合“函数式接口”定义,那么加不加该注解都没有影响。加上该注解能够更好的让编译器进行检查,如果编写的不是函数式接口,但是加上该注解的话编译器会报错。
实例
package lambda3;
/**
* @program: src
* @description: @FunctionalInterface 注解
* @author: SongZhiZe
* @create: 2022-10-23 22:21
**/
public class Program6 {
// 正确的函数式接口
public interface TestInterface{
// 抽象方法
public void sub();
// java.lang.Object中的public方法
public boolean equals(Object varl);
// 默认方法
public default void defaultMethod(){}
// 静态方法
public static void staticMethod(){}
}
// 错误的函数式接口(有多个抽象方法)
@FunctionalInterface
public interface TestInterface2{
void add();
// void sub();
}
}
系统内置函数式接口
java8的退出,是以Lambda重要特性,一起退出的,其中修通内置了一系列函数式接口;
在jdk的java.util.function包下,有一些列的内置函数式接口:好啦,小编今天的分享就结束啦,希望可以帮助到大家。