Java8新特性-行为参数化与lambda表达式

一、行为参数化

1.1 背景

软件工程必须要面对的一个问题就是,客户的需求总是在不断的变化当中的。我们在“你所不知道的Java8-前言”一文中已经讲到了客户挑苹果的需求在不断地变更,想要将我们的工作量降到最小就需要将代码行为进行参数化。以下是使用的“行为参数化”的思想编写的相应代码,如下所示。


public interface ApplePredicate {
    boolean test (Apple apple);
}

public class AppleHeavyWeightPredicate implements ApplePredicate{
    @Override
    public boolean test(Apple apple) {
        return apple.getWeight()>120;
    }
}


public class AppleGreenColorPredicate implements ApplePredicate{
    @Override
    public boolean test(Apple apple) {
        return "green".equals(apple.getColor());
    }
}
//使用ApplePredicate,使用不同的苹果挑选策略
 public static List<Apple> filterApples(List<Apple> source, ApplePredicate predicate){
        List<Apple> apples = new ArrayList<>();
        for (Apple apple : source) {
            if(predicate.test(apple)){
                apples.add(apple);
            }
        }
        return apples;
    }

1.2 策略设计模式

image.png
如上图所示,这个思想和“策略设计模式”相关,定义一个一系列算法,将它们封装起来(称之为“策略”),在代码运行时选择一个算法,这里的算法族时ApplePredicate,不同的策略是AppleHeavyWeightPredicate和AppleGreenColorPredicate。行为参数化就是所谓的让方法接受不同的行为(策略)作为参数,并在内部使用,来完成不同的行为。
后面,我们还使用了方法引用和lambda表达式来优化了这个需求,当时我们没有仔细探讨lambda表达式,只是使用了它,现在让我们来探讨一下。

二、函数式接口-lambda表达式

2.1 函数式接口

提到lambda表达式就不得不说函数式接口,因为lambda只用于函数式接口。所谓的函数式接口,就是Java 8中新增的一个特性,它是指仅包含一个抽象方法的接口。
Java 8提供了一些预定义的函数式接口,例如:Function、Consumer、Predicate、Supplier等。这些接口都只包含一个抽象方法,以便在使用Lambda表达式时可以简化代码,并且可以更方便地编写函数式风格的代码,也就是进行函数式编程。

  1. Function<T,R> 加工者

将T类型的对象转换为R类型的对象,示例代码如下所示:

Function<String, Integer> strToInt = Integer::parseInt; // 方法引用
int num = strToInt.apply("123"); // 将字符串"123"转换成整数123
  1. Consumer 消费者

对一个T类型的对象进行操作,不返回任何结果。例如:

Consumer<String> printStr = System.out::println; // 方法引用
printStr.accept("Hello World!"); // 打印输出"Hello World!"
  1. Predicate 断言

对一个T类型的对象进行判断,返回一个布尔类型的结果。例如:

Predicate<Integer> isPositive = num -> num > 0; // Lambda表达式
boolean result = isPositive.test(5); // 判断5是否大于0,返回true
  1. Supplier 生产者

不接受任何参数,返回一个T类型的结果。例如:

Supplier<String> getMessage = () -> "Hello World!"; // Lambda表达式
String message = getMessage.get(); // 返回字符串"Hello World!"
  1. Comparator 比较者

只包含一个抽象方法compare(T o1, T o2),用于比较两个对象的顺序。在Java中,Comparator通常用于对集合进行排序。例如,可以使用Comparator对一个List进行排序:

List<Integer> list = Arrays.asList(5, 2, 4, 1, 3);
Collections.sort(list, (a, b) -> a - b); // 使用Lambda表达式对集合进行升序排序
2.2 lambda表达式概述

Lambda表达式,也称为匿名函数,是Java 8中引入的一种新的语言特性,它为Java提供了一种新的编程方式。Lambda表达式可以使我们的代码更加简洁,提高编程效率。Lambda表达式实质上是一个匿名函数,它可以被看作是一个函数式接口的实例,因此它可以作为方法参数或返回值类型,或者赋值给一个变量。Lambda表达式的实质是一个对象,它实现了一个函数式接口。当Lambda表达式被调用时,它会执行函数式接口中的抽象方法。

2.3 lambda表达式与集合的配合

Lambda表达式和集合的配合使用是Java 8中的一个重要特性,它可以大大简化集合的操作,这些集合方法参数包含Java8预定义的一些函数式接口,例如filter的参数是Predicate断言接口,forEach的参数是Consumer消费者接口。
以下的思维导图展示了lambda的常见使用方法:

使用举例:

//1.遍历操作
List<String> list = Arrays.asList("apple", "banana", "orange", "pear");
list.forEach(str -> System.out.println(str));
//2.过滤操作
List<String> list = Arrays.asList("apple", "banana", "orange", "pear");
List<String> result = list.stream().filter(str -> str.length() > 5).collect(Collectors.toList());
//3.映射操作
List<String> list = Arrays.asList("apple", "banana", "orange", "pear");
List<String> result = list.stream().map(str -> str.toUpperCase()).collect(Collectors.toList());
//4.排序操作,升序排列
List<Integer> list = Arrays.asList(5, 2, 4, 1, 3);
List<Integer> result = list.stream().sorted((a, b) -> a - b).collect(Collectors.toList());
//5.分组操作,下面的代码使用Lambda表达式将集合中的字符串按照长度进行分组:
List<String> list = Arrays.asList("apple", "banana", "orange", "pear");
Map<Integer, List<String>> result = list.stream().collect(Collectors.groupingBy(String::length));
//6.拼接操作
List<String> list = Arrays.asList("apple", "banana", "orange", "pear");
String result = list.stream().collect(Collectors.joining(","));
//7.统计操作
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
long count = list.stream().count();
int sum = list.stream().mapToInt(Integer::intValue).sum();
double average = list.stream().mapToInt(Integer::intValue).average().orElse(0);

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值