Java Lambda表达式

Java Lambda表达式

Lambda表达式支持将代码块作为方法参数,Lambda表达式允许使用更简洁的代码来创建只有一个抽象方法的接口(这种接口被称为函数式接口)的实例,看一个例子

interface Command {
    void process(int[] target);
}

class ProcessArrary {
    public void process(int[] target, Command command) {
        command.process(target);
    }
}

public class CommandTest {
    public static void main(String[] args) {
        ProcessArrary processArrary = new ProcessArrary();
        int[] target = {3, 4, -1, 6};
      //ProcessArrary希望可以动态传入一段代码来处理数组 一般的写法大概就如下所示
        processArrary.process(target, new Command() {
            @Override
            public void process(int[] target) {
                int sum = 0;
                for(int tmp : target) {
                    sum += tmp;
                }
                System.out.println(sum);
            }
        });
    }
}

Lambda表达式完全可用于简化匿名内部类对象,因此可以将上述代码简化如下

package com.scitc.lambda;

interface Command {
    void process(int[] target);
}

class ProcessArrary {
    public void process(int[] target, Command command) {
        command.process(target);
    }
}

public class CommandTest {
    public static void main(String[] args) {
        ProcessArrary processArrary = new ProcessArrary();
        int[] target = {3, 4, -1, 6};
      //像极了JavaScript的箭头函数
        processArrary.process(target, (int[] num)->{
            int sum = 0;
            for(int tmp : num) {
                sum += tmp;
            }
            System.out.println(sum);
        });
    }
}

个人感觉非常的像JavaScript中的箭头函数,当然还可以进行简写,其简写的规则也和箭头函数差不多

如果表达式的代码块只有一条语句可以省略花括号

()-> System.out.println("Hello World");

表达式的形参只有一个,可以省略圆括号(类型也可以省略)

weather-> System.out.println("今天的天气是" + weather);

代码块中只有一条语句,即使需要返回值也可以简写成如下形式

(a, b)-> a + b

Lambda表达式和函数式接口

函数式接口:有且只有一个抽象方法的接口,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。

Lambda表达式的类型,也被称为“目标类型”,Lambda表达式的目标类型必须是“函数式接口”。

由于Lambda表达式的结果就是被当成对象,因此程序中完全可以使用Lambda表达式进行赋值

interface Command {
    int process(int[] target);
}

public class CommandTest {
    public static void main(String[] args) {
        int[] num = {1, 2, 3, 4};
        Command c = (arr) -> {
            int sum = 0;
            for(int tmp : arr) {
                sum += tmp;
            }
            return sum;
        };

        System.out.println(c.process(num));
    }
}

Lambda表达式实现的是匿名方法——因此它只能实现特定函数式接口中的唯一方法。这意味着表达式有如下两个限制:

  • lambda表达式的目标类型必须是明确的函数式接口
  • lambda表达式只能为函数式接口创建对象。lambda表达式只能实现一个方法,因此它只能为只有一个抽象方法的接口创建对象
Object c = (arr) -> {};
//Error:Target type of a lambda conversion must be an interface

方法引用与构造器引用

引用类方法

@FunctionalInterface
interface Convert {
    Integer convert(String from);
}

public class MethodRefer {
    public static void main(String[] args) {
        Convert convert1 = from-> Integer.valueOf(from);

        System.out.println(convert1.convert("100").getClass());
      //class java.lang.Integer
    }

}

上面代码调用convert1对象的conver()方法时——由于convert1方法是lambda表达式所创建的,convert()方法的执行体就是lambda表达式的代码块部分,所以结果为Integer

因为只有一行调用类的方法的代码,因此可以使用如下的方法引用进行替换

Convert convert1 = Integer::valueOf;

引用特定对象的实例方法

Convert convert2 = from -> "hello world".indexOf(from);
Integer val = convert2.convert("ll");
System.out.println(val);
//2

上面lambda表达式的代码块只有只有一行调用"hello world"对象的indexOf()实例方法,因此可以使用如下方法引用进行替换

Convert convert2 = "hello world"::indexOf;

引用某类对象的实例方法

@FunctionalInterface
interface MyTest {
    String test(String a, int b, int c);
}

public class LambdaTest {
    public static void main(String[] args) {
        MyTest myTest = (a, b, c) -> a.substring(b, c);

        String str = myTest.test("Hello World", 6, 11);

        System.out.println(str);
      // World
    }
}

阿吧阿吧阿吧,所以简写

MyTest myTest = String::substring;
String str = myTest.test("Hello World", 6, 11);
System.out.println(str);
//World

引用构造器

package com.scitc.lambda;

import javax.swing.*;

@FunctionalInterface
interface MyTest {
    JFrame win(String title);
}

public class LambdaTest {
    public static void main(String[] args) {
        MyTest myTest = (String a) -> new JFrame(a);
        JFrame jf = myTest.win("我的窗口");
      //弹了个窗口出来 不过这都是老玩意了 没弹出来也别在意
        System.out.println(jf);
    }
}

懂?

MyTest myTest = JFrame::new;
JFrame jf = myTest.win("我的窗口");
System.out.println(jf);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值