JDK8-lambda表达式

lambda对的演进及书写

  • 演进
    以Comparator接口为例。 代码调用Collections.sort方法对集合进行排序,其中第二个参数是一个匿名内部类,sort方法调用内部类中的compare方法对list进行位置交换,因为java中的参数类型只能是类或者基本数据类型,所以虽然传入的是一个Comparator类,但是实际上可以理解成为了传递compare方法而不得不传递一个Comparator类 ,这种方式显得比较笨拙,而且大量使用的话代码严重冗余,这种情况在java8中通过使用lambda表达式来解决。

    匿名内部类形式:

    Collections.sort(studentList, new Comparator<Student>() {
        @Override
        public int compare(Student o1, Student o2) {
            return Double.compare(o1.getScore(),o2.getScore());
        }
    });		
    

    lambda表达式形式:

    Collections.sort(studentList,(s1,s2)-> Double.compare(s1.getScore(),s2.getScore()));	
    
  • 多参数
    (1). lambda表达式的基本格式为(x1,x2)->{表达式…};
    (2). 在上式中,lambda表达式带有两个参数,此时参数类型可以省略,但两边的括号不能省略
    (3). 如果表达式只有一行,那么表达式两边的花括号可以省略
    例子:

    Collections.sort(studentList,(s1,s2)-> Double.compare(s1.getScore(),s2.getScore()));
    
  • 对于没有参数的情况
    (1).参数的括号不能省略,
    (2).其他语法同多参数

    new Thread(()-> System.out.println("hello, i am thread!")).start();
    
  • 对于一个参数的情况
    (1).可以省略参数的括号和类型
    (2).其他语法同多参数

    // item -> !(item instanceof MappingJackson2XmlHttpMessageConverter)
    List<HttpMessageConverter<?>> converters = messageConverters.stream()
        .filter(item -> !(item instanceof MappingJackson2XmlHttpMessageConverter))
        .collect(Collectors.toList());
    

lambda表达式内可以使用方法引用

lambda表达式内可以使用方法引用,仅当该方法不修改lambda表达式提供的参数。本例中的lambda表达式可以换为方法引用,因为这仅是一个参数相同的简单方法调用。

list.forEach(n -> System.out.println(n)); 
// 使用方法引用
list.forEach(System.out::println);  

然而,若对参数有任何修改,则不能使用方法引用,而需键入完整地lambda表达式,如下所示:

list.forEach((String s) -> System.out.println("*" + s + "*"));

lambda变量的使用

    public static void main(String[] args) {
        List<Integer> primes = Arrays.asList(new Integer[]{2, 3, 5, 7});
        // 局部变量被lambda表达式引用时为隐式的final变量。
        int factor = 2; // 基本类型不能修改值
        ArrayList<Integer> testList = new ArrayList<>(); // 引用类型不能修改引用,但是可以修改内容
        primes.forEach(element -> {
            testList.add(element); // 引用类型的局部变量可以修改内容
            System.out.println(factor + 2); // 基本类型,只能使用,不能改变值
            // 【注意】 编译会报'java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量'
            // factor ++;
            // 【注意】编译会报'java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量'
            // testList = new ArrayList<>();
        });
        System.out.println(testList);
    }

lambda当做方法参数传递

惰性求值方法

lists.stream().filter(f -> f.getName().equals("p1"))

如上示例,这行代码并未做什么实际性的工作,filter只是描述了Stream,没有产生新的集合。

及早求值方法

// f -> f.getName().equals("p1") 这个lambda表达式只是作为一个方法当参数传递,并没有这正的执行,在collect时才会执行
List<Person> list2 = lists.stream().filter(f -> f.getName().equals("p1")).collect(Collectors.toList());

如上示例,collect最终会从Stream产生新值,拥有终止操作。

理想方式是形成一个惰性求值的链,最后用一个及早求值的操作返回想要的结果。与建造者模式相似,建造者模式先是使用一系列操作设置属性和配置,最后调用build方法,创建对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值