2021-05-20 16:24

函数式编程(lambda表达式)简介

王姐姐

JavaEE

(1358)

(0)

收藏

1. 编程范式

1.1. 编程语言分类

命令式编程(Imperative Programming): 专注于”如何去做”,这样不管”做什么”,都会按照你的命令去做。解决某一问题的具体算法实现。

函数式编程(Functional Programming):把运算过程尽量写成一系列嵌套的函数调用。

逻辑式编程(Logical Programming):它设定答案须符合的规则来解决问题,而非设定步骤来解决问题。过程是事实+规则=结果。

1.2. 函数式编程

数式编程是种编程方式,它将电脑运算视为函数的计算,并避免变化状态和可变数据。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。

和指令式编程相比,函数式编程强调函数的计算比指令的执行重要,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而非设计一个复杂的执行过程。

和过程化编程相比,函数式编程里函数的计算可随时调用。

1.3. 特点

纯函数,函数的执行没有副作用也就是没有改变成员变量的值,返回值仅仅依赖于输入参数

可以是高阶函数,函数的参数和返回值都可以是函数。

2. Lambda表达式

2.1. 语法

函数式编程是用表达式或者声明来完成而不是语句来完成:

Lambda表达式:(a,b)->a+b

左边为参数列表,右边为函数体。

2.2. 作用

避免匿名内部类定义过多

可以让你的代码看起来很简洁

去掉了一堆没有意义的代码,只留下核心的逻辑

其实质属于函数式编程的概念

2.3. 示例

示例1:跳过前两个元素循环显示信息并返回集合

products = products.stream()
.skip(2)
.peek(System.out::println)
.collect(Collectors.toList());

ship(2)跳过前两个元素,peek类似forEach但是不“消费”stream,collect收集。

示例2:按着价格从低到高排序,java7的写法:

Collections.
sort
(
products
, 
new 
Comparator<Product>() {
    @Override
    
public int 
compare(Product o1, Product o2) {
        
return 
o1.getPrice().compareTo(o2.getPrice());
    }
});

java8的写法:

Collections.
sort
(
products
,((o1, o2) -> o1.getPrice().compareTo(o2.getPrice())));

或者

products = products.stream()
.sorted((a,b)->a.getPrice().compareTo(b.getPrice()))
.collect(Collectors.toList());

示例3:价格最高的类型为2的前三条产品,只打印标题并去重

products.stream()
.filter(p->p.getProductType().getId().equals(2))
.sorted((p1,p2)->p2.getPrice().compareTo(p1.getPrice()))
.limit(3)
.map(Product::getTitle)
.distinct()
.forEach(System.out::println);

3. lambda表达式引用实例方法

3.1. 无参无返回值

//
无参无返回值
@Test
public void 
testInstanceMethod5(){
    Product product = 
new 
Product();
    
//Runnable runnable = ()->product.hello();
    
Runnable runnable = product::hello;
    runnable.run();
}

3.2. 无参有返回值

@Test
public void 
testInstanceMethod1(){
    Product product = 
new 
Product();
    product.setId(1);
    
//Function<Product,Integer> funRef = p -> p.getId();
    
Function<Product,Integer> funRef = Product::getId;
//
注意这里的
Product
为类名
    
Integer id = funRef.apply(product);
    System.
out
.println(id);
}

或者

@Test
public void 
testInstanceMethod2(){
    Product product = 
new 
Product();
    product.setId(1);
    Supplier<Integer> supplier = product::getId;
//
注意这里的
product
为实例名而不是类名
    
System.
out
.println(supplier.get());
}

3.3. 有参无返回值

//
有参无返回值
@Test
public void 
testInstanceMethod4(){
    Product product = 
new 
Product();
    Consumer<Integer> consumer = (id)->product.setId(id);
    consumer.accept(12);
}

3.4. 有参有返回值

@Test
public void 
testInstanceMethod3(){
    BiFunction<String,String,Integer> biFunRef = String::indexOf;
    Integer index = biFunRef.apply(
"wanmait"
,
"it"
);
    System.
out
.println(index);
}

4. Lambda表达式引用静态方法

假如Product中有以下方法:
public static void showInfo(){    System.out.println("wanmait product...........");}public static String getInfo(){    return "wanmait  product...";}public static void setInfo(String info){    System.out.println("setInfo......"+info);}public static String sayHello(String name){    return "hello "+name;}public static int add(int a,int b){    return a+b;}

4.1. 无参无返回值

//
无参无返回值
@Test
public void 
testStaticMethod1(){
    
//Runnable runnable = ()->Product.showInfo();
    
Runnable runnable = Product::
showInfo
;
    runnable.run();
}

4.2. 无参有返回值

//
无参有返回值
@Test
public void 
testStaticMethod2(){
    
//Supplier<String> supplier = ()->Product.getInfo();
    
Supplier<String> supplier = Product::
getInfo
;
    System.
out
.println(supplier.get());
}

4.3. 有参无返回值

//
有参无返回值
@Test
public void 
testStaticMethod3(){
    
//Consumer<String> consumer = (info)->Product.setInfo(info);
    
Consumer<String> consumer = Product::
setInfo
;
    consumer.accept(
"hello"
);
}

4.4. 有一个参数有返回值

//
有参有返回值
@Test
public void 
testStaticMethod4(){
   
//Function<String,String> function= name->Product.sayHello(name);
   
Function<String,String> function= Product::
sayHello
;
    System.
out
.println(function.apply(
"wanma"
));
}

4.5. 两个参数有返回值

//
有两个参数有返回值
@Test
public void 
testStaticMethod5(){
    
//BiFunction<Integer,Integer,Integer> biFunction = (a,b)->Product.add(a,b);
    
BiFunction<Integer,Integer,Integer> biFunction = Product::
add
;
    
int 
result = biFunction.apply(4,5);
    System.
out
.println(result);
    
//
或者
    
BinaryOperator<Integer> binaryOperator = Product::
add
;
    
int 
result2 = binaryOperator.apply(5,6);
    System.
out
.println(result2);
}

5. Lambda表达式引用构造函数

//
引用构造函数
@Test
public void 
testConstructor(){
   
//Supplier<Product> supplier = ()->new Product();
   
Supplier<Product> supplier = Product::
new
;
   Product product = supplier.get();
}


0条评论

点击登录参与评论