Lambda表达式

Lambda是一个匿名函数,可以理解为一段可以传递的代码(将代码像数据一样传递);可以写出更简洁、更灵活的代码;作为一种更紧凑的代码风格,是Java语言表达能力得到提升。

lambda语法

lambda语法:(定义参数)->(定义方法体)

//        语法格式一: 无参数 无返回值  () -> System.out.println("语法格式一");
        Runnable runnable = () -> System.out.println("语法格式一");
        runnable.run();

//        语法格式二: 有一个参数 并且无返回值 (x) -> System.out.println(x+"语法格式二");
        Consumer<String> customer = (x) -> System.out.println(x + "语法格式二");
        customer.accept("测试");

//       语法格式三: 有两个以上的参数,有返回值,并且lambda体中有多条语句
        Comparator<Integer> comparator = (x, y) -> {
            System.out.println("语法格式三");
            return Integer.compare(x, y);
        };
        System.out.println("返回值" + comparator.compare(1, 2));
//        语法格式四: 有两个以上的参数,有返回值, 若lambda体中只有一条语句,return和大括号都可以省略
        Comparator<Integer> comparator2 = (x, y) -> Integer.compare(x, y);
        System.out.println("返回值" + comparator2.compare(1, 2));

方法引用

若 Lambda 表达式体中的内容已有方法实现,则我们可以使用“方法引用”
语法格式:
对象 :: 实例方法
类 :: 静态方法
类 :: 实例方法

@Test
public void test01(){
    PrintStream ps = System.out;
    Consumer<String> con1 = (s) -> ps.println(s);
    con1.accept("aaa");

    Consumer<String> con2 = ps::println;
    con2.accept("bbb");
}

注意:Lambda 表达实体中调用方法的参数列表、返回类型必须和函数式接口中抽象方法保持一致

构造器引用

格式:
ClassName :: new

@Test
public void test04(){
    Supplier<List> sup1 = () -> new ArrayList();

    Supplier<List> sup2 = ArrayList::new;
}

注意:需要调用的构造器的参数列表要与函数时接口中抽象方法的参数列表保持一致

函数式接口

/**
 * java8内置四大函数式接口
 * Consumer<T>: 消费型接口
 * void accept(T t)
 * Supplier<T>: 供给型接口
 * T get();
 * Function<T,R>: 函数型接口
 * R apply(T t);
 * predicate<T?: 断言型接口
 * boolean test(T t)
 */
@Test
public void test() {
    happy(10, (x) -> System.out.println("我今天花了" + x));
}


public void happy(double money, Consumer<Double> con) {
    con.accept(money);
}

Stream API

java stream bigdecimal 加总 java stream lambda_java

创建

stream()

//       集合或数组通过stream()
        List<String> list = new ArrayList<>();
        Stream<String> stream = list.stream();
        String[] a = new String[10];
        Stream<String> stream1 = Arrays.stream(a);
//        通过Stream类中的静态方法of()
        Stream<String> b = Stream.of("aa", "bb");

筛选 / 切片

filter:接收 Lambda ,从流中排除某些元素
limit:截断流,使其元素不超过给定数量
skip(n):跳过元素,返回一个舍弃了前n个元素的流;若流中元素不足n个,则返回一个空流;与 limit(n) 互补
distinct:筛选,通过流所生成的 hashCode() 与 equals() 取除重复元素

List<Employee> emps = Arrays.asList(
    new Employee(101, "Z3", 19, 9999.99),
    new Employee(102, "L4", 20, 7777.77),
    new Employee(103, "W5", 35, 6666.66),
    new Employee(104, "Tom", 44, 1111.11),
    new Employee(105, "Jerry", 60, 4444.44)
);

@Test
public void test01(){
    emps.stream()
        .filter((x) -> x.getAge() > 35)
        .limit(3) //短路?达到满足不再内部迭代
        .distinct()
        .skip(1)
        .forEach(System.out::println);

}

映射

map:接收 Lambda ,将元素转换为其他形式或提取信息;接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
flatMap:接收一个函数作为参数,将流中每一个值都换成另一个流,然后把所有流重新连接成一个流
map:

@Test
public void test02(){
    List<String> list = Arrays.asList("a", "b", "c");
    list.stream()
        .map((str) -> str.toUpperCase())
        .forEach(System.out::println);
}

flatMap:

public Stream<Character> filterCharacter(String str){
    List<Character> list = new ArrayList<>();
    for (char c : str.toCharArray()) {
        list.add(c);
    }

    return list.stream();
}

@Test
public void test03(){
    List<String> list = Arrays.asList("a", "b", "c");
    Test02 test02 = new Test02();
    list.stream()
        .flatMap(test02::filterCharacter)
        .forEach(System.out::println);
}

排序

sorted():自然排序
sorted(Comparator c):定制排序

@Test
public void test04(){
    List<Integer> list = Arrays.asList(1,2,3,4,5);
    list.stream()
        .sorted() //comparaTo()
        .forEach(System.out::println);
}

查找 / 匹配

allMatch:检查是否匹配所有元素
anyMatch:检查是否至少匹配一个元素
noneMatch:检查是否没有匹配所有元素
findFirst:返回第一个元素
findAny:返回当前流中的任意元素
count:返回流中元素的总个数
max:返回流中最大值
min:返回流中最小值

@Test
public void test8() {
    List<Employee> employees = Arrays.asList(new Employee("张三", 41),
            new Employee("李四", 17),
            new Employee("王五", 18));
    boolean b = employees.stream().anyMatch((e) -> e.getName().equals("张"));
    System.out.println(b);
    Optional<Employee> op = employees.stream().max((a, c) -> Integer.compare(a.getAge(), c.getAge()));
    System.out.println(op.get());
}

归约 / 收集

归约:reduce(T identity, BinaryOperator) / reduce(BinaryOperator) 可以将流中的数据反复结合起来,得到一个值

@Test
public void test9() {
    List<Integer> list = Arrays.asList(1, 2, 3, 4);
    Integer sum = list.stream().reduce(0, (x, y) -> x + y);
    System.out.println(sum);
}

收集:collect 将流转换成其他形式;接收一个 Collector 接口的实现,用于给流中元素做汇总的方法

@Test
public void test10() {
    List<Employee> employees = Arrays.asList(new Employee("张三", 41),
            new Employee("李四", 17),
            new Employee("王五", 18));
    List<Integer> list = employees.stream().map(Employee::getAge).collect(Collectors.toList());
    System.out.println(list);
}