Lambda表达式和Stream类的使用

版权声明:发扬开源精神,欢迎大家转载对自己有用的文章(●'◡'●) https://blog.csdn.net/jacksonary/article/details/82289427

Lambda表达式也叫闭包,允许把函数作为一个方法的参数,可以将代码变得简介紧凑,核心思想是将面向对象中的传递数据变成传递行为。对于只有单一方法的匿名类会显得很繁琐,Lambda表达式可以让我们直接将某种功能作为参数,可以让上面的行为变得更加简洁。关于Lambda官方详细文档戳这里

1.基本语法为expression=(parameters) -> action(参数、箭头、动作实现):

// 方式1
(parameters) -> expression
// 方式2
(parameters) -> {statements;}

【说明】

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数;
  • 可选参数圆括号:一个参数无须定义圆括号,但多个参数需要定义圆括号;
  • 可选花括号:如果主体中只包含一个语句,就不需要使用花括号了,否则需要使用;
  • 可选的返回关键字:如果主体中只有一个表达式则编译器会自动返回值,如果多个表达式使用花括号,就需要指明返回一个值;

2.使用场景,下面是一些用例代码:


public class LambdaTest {
    public static void main(String[] args) {

        LambdaTest lambdaTest = new LambdaTest();

        // 声明类型
        MathOperation add = (int a, int b) -> a + b;

        // 不声明类型
        MathOperation sub = (a, b) -> a - b;

        // 使用花括号返回值
        MathOperation multi = (a, b) -> {
            return a * b;
        };

        // 没有大括号及返回语句
        MathOperation div = (a, b) -> a / b;

        System.out.println(lambdaTest.operate(2, 3, add));
        System.out.println(lambdaTest.operate(3, 2, sub));
        System.out.println(lambdaTest.operate(2, 3, multi));
        System.out.println(lambdaTest.operate(10, 5, div));


        String hello = "Hello ";

        GreetingService greetingService = message -> System.out.println(hello + message);

        greetingService.sayMessage("China");
        greetingService.sayMessage("Janey");

        // 用()->{}代替匿名类
        new Thread(() -> System.out.println("lambda")).start();

        List<String> list = Arrays.asList(new String[]{"c", "b", "h"});

        // 遍历List的方法1
        list.forEach(l -> System.out.println(l));
        System.out.println("=================");

        // 遍历List的方法2,其中::代表方法引用的操作符
        list.forEach(System.out::println);

        // 排序,其实有点类似上面的匿名类
        Comparator<String> stringComparator = (str1, str2) -> str1.compareTo(str2);
        list.sort(stringComparator);
    }

    interface MathOperation {
        int operation(int a, int b);
    }

    interface GreetingService {
        void sayMessage(String message);
    }

    private int operate(int a, int b, MathOperation mathOperation) {
        return mathOperation.operation(a, b);
    }
}

关于上述的方法引用操作符是::,基本是下面的形式:

objectName::instanceMethod
ClassName::staticMethod
ClassName::instanceMethod

在遍历List时用到的System.out::printlnx -> System.out.println(x)是一样的,Math::max就等同于(x,y) -> Math.max(x,y)

 这一块结合昨天遇到的Stream很好用,Stream是一个来自数据源的元素队列并支持聚合操作:

  • 元素是特定类型的对象,形成一个队列,Stream并不会存储元素,而是按需计算;
  • 数据源是Stream的来源,可以是数组、集合等对象;
  • 聚合操作,就是按需进行的一些操作,如过滤、遍历、匹配等操作;

下面是之前写的一些常用方法的案例:

// 初始化一个流
Stream stream = Stream.of("a", "b", "c");

// 将数组转化为一个流
String[] arr = new String[]{"cb", "b", "pb", "ub", "b"};
Stream stream1 = Stream.of(arr);

// 将一个集合对象转为一个流
List<String> list = Arrays.asList(arr);
Stream stream2 = Stream.of(list);

Object collect = stream2.sorted().collect(Collectors.toList());

// 1.1 map方法实现遍历映射操作(有点类似于覆盖源数据的意思),collect方法是得到操作后的集合
List<String> list1 = list.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println(list1);

// 1.2 更新值
List<String> list2 = list.stream().map(s -> s + "ha").collect(Collectors.toList());
System.out.println(list2);

// 1.3 遍历还可以直接用forEach
stream.forEach(s -> System.out.println(s));

// 2.1 利用filter进行过滤,对过滤后的流再使用collect方法转成对应的集合
List<String> list3 = list.stream().filter(s -> !s.contains("c")).collect(Collectors.toList());
System.out.println(list3);

// 3. 对流进行忽略或者limit操作(类似于MySQL中limit),skip(2)就是跳过流的前2个,返回前1个
List<String> list4 = list.stream().skip(2).limit(1).collect(Collectors.toList());
System.out.println(list4);

// 4. 排序
List<String> list5 = list.stream().sorted().collect(Collectors.toList());
System.out.println(list5);

// 5. 去重,distinct方法可以将流中的重复元素去除
List<String> list6 = list.stream().distinct().collect(Collectors.toList());
System.out.println(list6);

// 6. 匹配, allMatch、anyMatch、noneMatch
// 6.1 anyMatch只要有一个元素符合predicate(这里就是a)就返回true
boolean anyMatch = list.stream().anyMatch(s -> s.equals("i"));
System.out.println(anyMatch);

// 6.2 noneMatch匹配不满足条件的,只有全部不满足才返回true
boolean noneMatch = list.stream().noneMatch(s -> s.contains("a"));
System.out.println(noneMatch);

// 6.3 allMatch匹配满足条件的,只有全部满足条件的才返回true
boolean allMatch = list.stream().allMatch(s -> s.contains("b"));
System.out.println(allMatch);


List<Integer> integers = filterVersions(2017);
System.out.println(integers);

猜你喜欢

转载自blog.csdn.net/jacksonary/article/details/82289427