前序:

1:Lambda 表达式 及支持 jdk 8 或以上 版本。

    2:学习 Lambda 表达式需要了解 “函数式接口”。

    3:用过Idea 编辑器的朋友应该知道,idea 已经支持 lambda 表达式,即使你和我一样还不了解 Lambda表达式 ,你若代码中出现了可以更改成Lambda表达式的代码,idea会自动提示你。
  
   4:即便支持就更要学习一下,要不然你会和我一样闹出笑话(真人真事)。
 讲个笑话,最开始接触idea(eclipse 转 idea) 的时候,用Runnable 时,idea 出现黄色警告⚠,那是我第一次接触Lamdba 表达式,当时就很好奇跟同事讲 idea 居然可以这样写。现在想起那个同事的表情,就知道他当时为什么不理我了。

 


 

Lambda 表达式基础语法总结:

  1. 语法格式一:无参,无返回值
语法:() -> 具体的实现 

演示对象:我们拿 Runable 来演示
  • 传统代码

  • /**
         * 测试
         * @param args
         */
        public static void main(String[] args) {
    
            Runnable runnable=new Runnable() {
                @Override
                public void run() {
                    System.out.println("传统方式 无参,无返回值");
                }
            };
    
            runnable.run();
        }
    
    // 运行结果
    传统方式 无参,无返回值


  • Lambda 表达式:有没有眼前一亮,是不是很简单。

  • /**
         * 测试
         * @param args
         */
        public static void main(String[] args) {
    
            Runnable runnable= () -> System.out.println("Lambda 无参,无返回值");
    
            runnable.run();
        }
    
    //运行结果
    Lambda 无参,无返回值


  1. 语法格式二:有一个参数,并且无返回值
语法:(x)-> 具体的实现
演示对象:自定义 ”函数式接口“

与上面不同:这里有了一个 x ,x:表示参数,
  • 自定义一个”函数式接口” 

  • /**
     * @author Administrator
     * @version 1.0
     * @describe
     * @date 2019/12/21 20:23
     */
    @FunctionalInterface
    public interface FunctionTest {
        /**
         * 用于对这个数值 进行处理,
         * 交由 子类实现。
         * @param num
         */
        void calculate(int num);
    
    }


  • Lambda 表达式实现:这里的 x 表示形参,是calculate方法 传进来的 10,你也可以不取名为x , 其它的都可以。

  • /**
         * 测试
         * @param args
         */
        public static void main(String[] args) {
    
            //需求:打印一个数值中的偶数
            FunctionTest test =(x) ->{
                for (int i = 0; i < x; i++) {
                    if (i % 2 == 0) {
                        System.out.println(i);
                    }
                }
            };
            test.calculate(10);
    
    
        }
    
    // 运行结果
    
    0
    2
    4
    6
    8


  1. 语法格式三:若有一个参数,小括号省略不写
x -> 具体的实现

演示对象:用 语法格式二 来做演示
  • 代码演示:忽略 x 的小括号,


    /**
         * 测试
         * @param args
         */
        public static void main(String[] args) {
    
            //需求:打印一个数值中 2的倍数
            FunctionTest test = x ->{
                for (int i = 0; i < x; i++) {
                    if (i % 2 == 0) {
                        System.out.println(i);
                    }
                }
            };
            test.calculate(10);
        }
    
    #运行结果 
    0
    2
    4
    6
    8


  1. 语法格式四:若存在多个参数、多条语句时,那么必须 带 {}。
(x,y) ->{具体的实现}
演示对象:自定义” 函数接口 “,
强调:若存在多个参数时,必须带上"小括号",取什么名无所谓,不重复即可。
  • 自定义”函数接口“

  • /**
     * @author Administrator
     * @version 1.0
     * @describe
     * @date 2019/12/21 20:23
     */
    @FunctionalInterface
    public interface FunctionTest {
        /**
         * 用于对两个数值 进行处理,
         * 交由 子类实现。
         * @param num1
         * @param num2
         */
        void calculate(double num1,double num2);
    
    }


  • Lambda 表达式实现方式一:计算两个数的和
/**
     * 测试
     * @param args
     */
    public static void main(String[] args) {

        //需求:打印一个数值中 2的倍数
        FunctionTest test = (x,y) -> System.out.println(String.format("%s + %s = %s",x,y,x+y));
        test.calculate(5,3);
    }
  // 运行结果
  5.0 + 3.0 = 8.0
  • Lambda 表达式实现方式二:计算两个数的 积
/**
     * 测试
     * @param args
     */
    public static void main(String[] args) {

        //需求:打印一个数值中 2的倍数
        FunctionTest test = (x,y) -> System.out.println(String.format("%s x %s = %s",x,y,x*y));
        test.calculate(4,6);
    }
  // 运行结果
  4.0 x 6.0 = 24.0
  • Lambda表达式实现方式三:上面都是 单条语句的,下面实现多条语句,分别输出两个参数的值就行了。
/**
     * 测试
     * @param args
     */
    public static void main(String[] args) {

        //需求:打印一个数值中 2的倍数
        FunctionTest test = (x,y) ->{
            System.out.println(String.format("x = %s",x));
            System.out.println(String.format("y = %s",y));
        };
        test.calculate(4,6);
    }

//运行结果
x = 4.0
y = 6.0
  • 传统方式实现:
第一种方式:创建一个子类由子类来实现。
  这里就不介绍 第一种方式了,太麻烦还得创建一个新的类。
第二种方式:采用匿名内部类的方式进行实现。
  • 采用 匿名内部类的方式进行实现两个数(4 和 5)的和
public static void test(double x,double y,FunctionTest test){
        test.calculate(x,y);
    }

      /**
     * 测试
     * @param args
     */
    public static void main(String[] args) {

       //匿名内部类的方式进行实现
        test(4, 5, new FunctionTest() {
            @Override
            public void calculate(double num1, double num2) {
                System.out.println(num1* num2);
            }
        });

    }


// 运行结果:
    20.0

  5. 语法格式五:若存在多个参数、单条语句时,return 或 {} 可以省略不写。

  • 代码上面已经演示过了,但是上面的案例都是无返回值的,那么看看有返回值的情况下是怎么样的
  • 更改一下 接口方法。
/**
 * @author Administrator
 * @version 1.0
 * @describe
 * @date 2019/12/21 20:23
 */
@FunctionalInterface
public interface FunctionTest {
    /**
     * 用于对这个数值 进行处理,
     * 交由 子类实现。
     * @param num1
     * @param num2
     */
    double calculate(double num1,double num2);


}
  • 代码演示 有返回值的 Lambda 表达式
/**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        FunctionTest test=(x,y) ->{
            double result = x * y;
            return result;
        };

        System.out.println(test.calculate(10,2));

    }


# 运行结果
20.0

  6. 语法格式六:Lambda 表示的参数列表的参数类型可以省略不写,因为JVM编辑器通过上下文推断出,数据类型,即“类型推断”。

 


 

JAVA 内置四大核心 函数接口

上面的案例中,每写一个案例,都需要自己创建一个 “函数接口”,在java 中已经为我们内置好了一些“函数接口”,对于一些普通的操作,我们就无需再自己去创建接口。但是面对比较复杂的业务时,还是需要我们自己来创建的。

只要这四大函数接口能充分掌握了,那么其他的也就水到渠成了。
  • 四大核心 函数接口 分类

名称

定义

方法

 解释

Consumer<T>

消费型接口

void accept(T t);

消费型接口,主要用于做一些无返回值数据处理,最简单的案例就是 在里面输出一句话 System.out.println("hello word!")。 

Supplier<T>

供给型接口

T get()

供给型接口,主要是用于提供一些资源响应。如Random.nextInt()方法,它就是产生一些随机数并返回。默默的奉献着,不收取人任何回报。

Function<T,R>

函数型接口

R apply(T t)

函数型接口,有两个参数(T、R),对 T 进行处理,返回 R。 

Predicate<T>

断言型接口

boolean test(T t)

主要用于做一些判断型操作。 

 

 

 

 

 

 

 

 

 

  •  Consumer 案例演示
/**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        List<Integer> numbers=new ArrayList<>();
        numbers.add(52);
        numbers.add(18);
        numbers.add(45);
        numbers.add(12);
        numbers.add(63);


        //案例: 将上列数据 按照 升序进行排列
        Consumer<List<Integer>> consumer=(t)->{
            int size = numbers.size();
            for (int i = 0; i < size-1; i++) {
                for (int j = 0; j < size-1-i; j++) {
                    //比较两个整数的大小
                    if (numbers.get(j)>numbers.get(j+1)) {
                        Integer temp = numbers.get(j);
//                  使用list集合的set方法,找到位置并将数字赋值到该位置
                        numbers.set(j, numbers.get(j+1));
                        numbers.set(j+1,temp);
                    }
                }
            }
        };
        consumer.accept(numbers);

        for (int i = 0; i < numbers.size(); i++) {
            System.out.println(numbers.get(i));
        }

    }
  • Consumer 案例结果
12
18
45
52
63
  • 也可以这样实现。
/**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        List<Integer> numbers=new ArrayList<>();
        numbers.add(52);
        numbers.add(18);
        numbers.add(45);
        numbers.add(12);
        numbers.add(63);


        sort(numbers,(t)->{
            int size =numbers.size();
            for (int i = 0; i < size-1; i++) {
                for (int j = 0; j < size-1-i; j++) {
                    //比较两个整数的大小
                    if (numbers.get(j)>numbers.get(j+1)) {
                        Integer temp = numbers.get(j);
//                  使用list集合的set方法,找到位置并将数字赋值到该位置
                        numbers.set(j, numbers.get(j+1));
                        numbers.set(j+1,temp);
                    }
                }
            }

        });
        //打印 排序后的结果
        System.out.println(numbers);


    }
  // 自定义方法,这样的方式会更加灵活,
    public static void sort(List<Integer> list, Consumer consumer){
        consumer.accept(list);
    }

  // 运行结果
  [12, 18, 45, 52, 63]
  • Supplier 案例演示:
需求:根据用户输入条件 匹配 用户信息并返回。
如:用户输入 一个 数据 16,那么匹配用户集合中包含 16 的数据信息。并做返回。

定义一个 三条用户数据信息,存放到 集合中。
然后 采用 Supplier 供给型函数接口 实现数据匹配。
/**
     * 测试 定义一个map list 模拟 用户信息,
     * @param args
     */
    public static void main(String[] args) {
       List<Map<String,String>> nameList=new ArrayList<>();
       Map<String,String> user1=new HashMap<>(5);
        user1.put("姓名","张三");
        user1.put("年龄","18");
        user1.put("性别","男");
        nameList.add(user1);

        Map<String,String> user2=new HashMap<>(5);
        user2.put("姓名","春丽");
        user2.put("年龄","16");
        user2.put("性别","女");
        nameList.add(user2);

        Map<String,String> user3=new HashMap<>(5);
        user3.put("姓名","小明");
        user3.put("年龄","16");
        user3.put("性别","男");
        nameList.add(user3);

        //根据 数据为16 的用户信息
        List< Map<String,String>> maps= queryUserName( nameList,()->"16");

        System.out.println(maps);

    }

    /**
     * 根据用户输入条件,匹配用户信息并返回
     * @param mapList
     * @param supplier
     * @return
     */
    public static  List< Map<String,String>> queryUserName( List<Map<String,String>> mapList,Supplier<String> supplier){
        List< Map<String,String>> mapList1=new ArrayList<>();

        for (int i = 0; i < mapList.size(); i++) {
            Map<String,String> map=mapList.get(i);
            for (String key: map.keySet()){
                if (map.get(key).equals(supplier.get())) {
                    mapList1.add(map);
                    continue;
                }
            }

        }

        return mapList1;
    }
  • Supplier 案例 运行结果:
//包含 16 的数据 有 两条

[{姓名=春丽, 年龄=16, 性别=女}, {姓名=小明, 年龄=16, 性别=男}]
  • 若上面的案例太复杂,可以简单的使用 Supplier :实际上在工作中,肯定不会这么写(如下),业务肯定这个复杂,一个复杂 一个简单的对比,只是想说明 supplier 的作用。更想说明 Lambda 表达式的好处。
/**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        //生成一个 随机数
        Supplier supplier =() -> new Random().nextInt();
        System.out.println(supplier.get());

    }

    // 运行结果
    1144876318
  • Function 案例展示:
需求:对字符串进行处理。
/**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        //小写处理
        String toLowerCase = strHandler("Hello, Word!",(t)-> t.toLowerCase() );
        System.out.println(toLowerCase);
        //大写处理
        String toUpperCase = strHandler("Hello, Word!",(t)-> t.toUpperCase() );
        System.out.println(toUpperCase);

    }

    /**
     * 对字符串进行处理
     * @param str
     * @param function
     * @return
     */
    public static String strHandler(String str, Function<String,String> function){
        return function.apply(str);
    }
  • Function 案例 运行结果:
hello, word!
HELLO, WORD!
  • Predicate 案例展示:
检测 用户是否输入的是数字
/**
     * 测试
     * @param args
     */
    public static void main(String[] args) {


        // 测试数据
        String str= "12";

       boolean bool= numberVerification(str,(s)->{
            Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)?$");

            Matcher isNum = pattern.matcher(s);
            if (!isNum.matches()) {
                return false;
            }
            return true;
        });

        System.out.println(bool);
        
    }

    /**
     * 检测用户输入是否为数字
     * @param str
     * @param predicate
     * @return
     */
    public static boolean numberVerification(String str, Predicate<String> predicate){
        return predicate.test(str);
    }
  • Predicate 案例运行结果:
true

 

 最后总结:

说实话,我案例表述的不是很明白,若你想要好好的学习一下 Lambda 表达式 建议 去 B站 找视频系统学习。以上案例 都是我看视频时,练手用的代码。至于质量而已,我能明白就行了,我又不是行业大佬,也没想过能写出高质量博客,只是记录一下我的学习过程罢了。
你看了,有所感悟,我也很高兴,若是没有帮助,关掉就行了。

 

 

 

后续更新中....