栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java8新特性——函数式编程(lambda表达式)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java8新特性——函数式编程(lambda表达式)

文章目录
  • 前言
  • 1.函数式接口
  • 2.函数式编程
    • 2.1 Lambda表达式标准格式
    • 2.2 Lambda表达式举例
    • 2.3 函数式编程的好处
    • 2.4 常用函数式接口
      • 1. Supplier
      • 2.Consumer
      • 3.Predicate
      • 4.Function


前言

java是面向对象语言,但是有时候为了更加方面的实现某些功能,引入了函数式编程,具体可见本文2.2中的例子。
本文首先介绍了函数式编程中必不可少的函数式接口,之后介绍了lambda表达式的基本格式、优点,以及常见的4个函数式接口。


1.函数式接口
  • 有且仅有一个抽象方法的接口

格式:

修饰符 interface 接口名称 {
public abstract 返回值类型 方法名称(可选参数信息);
// 其他非抽象方法内容
}

举例:
注解:@FunctionalInterface

@FunctionalInterface
public interface MyFunctionalInterface {
void myMethod();
}
2.函数式编程

函数式编程中的函数指的不是程序中的函数(方法),而是数学中的函数即映射关系,如:y=sin(x),描述数据(函数)之间的映射,同时需要保证相同的输入始终能得到相同的输出。

函数式编程不会保留计算中间的结果,因此也可以说是无状态的。函数式编程可以将一个函数的执行结果再交由另一个函数去处理。

Java8通过Lambda表达式与方法引用等,实现函数式编程,可将其可定义为一种简洁、可传递的匿名函数

2.1 Lambda表达式标准格式
  • 两种格式:
(parameters) -> expression

(parameters) ->{ statements; }
  • parameters:类似方法中的形参列表,这里的参数是函数式接口里的参数,多个参数逗号隔开
  • ->:可以理解为被用于
  • 方法体:
  • List item
    • 表达式,如果只有一句的话当前表达式即为返回值,不需要写return
    • 代码:用{}括起来,如有返回值需要return
      举例:
// 返回给定字符串的长度(隐含return语句) 
(String str) -> str.length()

// 始终返回233的无参方法(隐含return语句) 
() -> 233

// 返回当前用户是否年龄大于20岁,返回一个boolean值(隐含return语句) 
(User user) -> user.getAge() > 20

// 包含多行表达式,需用花括号括起来,并使用return关键字返回
(int x, int y) -> { 
    int z = x * y; 
    return x + z; 
}
2.2 Lambda表达式举例

我们此处以通过Runnable接口实现类的创建线程为例,由于Runnable接口只有一个run()方法,所以这里从之前的直观写法到lambda表达式进行代码演示。

  1. 通过创建一个Runnable接口实现类来实现
public class TestThread {
    @Test
    public void testThread1(){
        Thread thread = new Thread(new MyRunnable(), "thread1");
        thread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("主线程" + i);
        }
    }

}

class MyRunnable implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread() + "正在执行:" + i);
        }
    }
}
  1. 通过匿名内部类
    @Test
    public void testThread2(){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread() + "正在执行:" + i);
                }
            }
        }, "thread1");
        thread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("主线程" + i);
        }

    }
  1. lambda表达式
    @Test
    public void testThread3(){
        Thread thread = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread() + "正在执行:" + i);
            }
        }, "thread1");
        thread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("主线程" + i);
        }

    }
2.3 函数式编程的好处
  1. 减少业务逻辑和代码的分歧。他允许我们在更高层次更自然的描述业务逻辑。让代码直接描述“你想做什么”,而不是“你想怎样去做”。
  2. 延迟执行:以lambda表达式为例,通过下面的例子可以看出lambda表达式是现将代码逻辑传送进去,符合逻辑才执行,此时传进去的flag为2,不符合逻辑,则lambda中的逻辑均不执行
public class TestThread {

    @Test
    public void testDelay(){
        printLog(2, () -> {
            System.out.println("lambda执行");
            return "a" + "b" + "c";
        });

    }

    private void printLog(int flag, MessageBuilder message){
        if(flag == 1){
            System.out.println(message.buildMessage());
        }
    }
    
}

interface MessageBuilder {
    String buildMessage();
}
2.4 常用函数式接口
  • 对于各个常用接口,这里仅介绍他们的抽象方法,对于Consumer等还有一些默认方法。
  • 这四个接口,会通过后面的文章具体解析编程时的应用。
1. Supplier

对外提供”一个符合泛型类型的对象
数据。

@FunctionalInterface
public interface Supplier {
    T get();
}

举例:

import java.util.function.Supplier;
public class Demo08Supplier {
    private static String getString(Supplier function) {
        return function.get();
    } public static void main(String[] args) {
        String msgA = "Hello";
        String msgB = "World";
        System.out.println(getString(() ‐> msgA + msgB));
    }
}
2.Consumer

正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,其数据类型由泛型决定

@FunctionalInterface
public interface Consumer {
    void accept(T t);
}
import java.util.function.Consumer;
public class Demo09Consumer {
    private static void consumeString(Consumer function) {
        function.accept("Hello");
    } public static void main(String[] args) {
        consumeString(s ‐> System.out.println(s));
    }
}
3.Predicate

对某种类型的数据进行判断,从而得到一个boolean值结果。

@FunctionalInterface
public interface Predicate {
    boolean test(T t);
}
import java.util.function.Predicate;
public class Demo15PredicateTest {
    private static void method(Predicate predicate) {
        boolean veryLong = predicate.test("HelloWorld");
        System.out.println("字符串很长吗:" + veryLong);
    } public static void main(String[] args) {
        method(s ‐> s.length() > 5);
    }
}
4.Function

用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件

@FunctionalInterface
public interface Function {
    R apply(T t);
}
import java.util.function.Function;
public class Demo11FunctionApply {
    private static void method(Function function) {
        int num = function.apply("10");
        System.out.println(num + 20);
    } public static void main(String[] args) {
        method(s ‐> Integer.parseInt(s));
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/858072.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号