04lambda表达式学习笔记

本文介绍 Java 8 中引入的 Lambda 表达式的语法和应用案例,包括列表迭代、事件监听、Predicate 接口使用、Map 映射及 Reduce 聚合等常见应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

               lambda表达式学习笔记

1 lambda语法

Printer.java

package com.tangguanlin.lambda;
public interface Printer {
    void printer(String val);
}

LambdaDemo.java

package com.tangguanlin.lambda;
/**
 * 作者:汤观林
 * 完成日期:2021年05月04日
 */
public class LambdaDemo {

    public void printSomething(String something, Printer printer){
        printer.printer(something);
    }
}

LambdaDemoTest.java

package com.tangguanlin.lambda;
/**
 * 不用lamdba表达式的实现
 * 作者:汤观林
 * 完成日期:2021年05月04日
 */
public class LambdaDemoTest {
    public static void main(String[] args) {
        LambdaDemo lambdaDemo = new LambdaDemo();
        String something  ="tewssss";

        //传统方式实现接口
        Printer printer = new Printer() {
            @Override
            public void printer(String val) {
                System.out.println(val);
            }
        };

        //用lamdba表达式实现接口 简化0
        Printer printer0 = (String val)->{
            System.out.println(val);
        };

        //用lamdba表达式实现接口 简化1
        Printer printer1 = (val)->{
            System.out.println(val);
        };

        //用lamdba表达式实现接口 简化2
        Printer printer2 = (val)->System.out.println(val);

        //用lamdba表达式实现接口 简化3
        Printer printer3 = val->System.out.println(val);

        //用lamdba表达式实现接口 简化4
        lambdaDemo.printSomething(something,val->System.out.println(val));

        lambdaDemo.printSomething(something,printer1);
    }
}

2 list转map list过滤

Person.java

package com.tangguanlin.lambda;
/**
 * 作者:汤观林
 * 完成日期:2021年05月04日
 */
public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public String getName() {
        return name;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

ListToMap.java

package com.tangguanlin.lambda;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * list转map list过滤
 * 作者:汤观林
 * 完成日期:2021年05月04日
 */
public class ListToMap {
    public static void main(String[] args) {

        List<Person> personList = new ArrayList<Person>();
            personList.add(new Person("zhangsan",11));
            personList.add(new Person("lisi",12));
            personList.add(new Person("wangwu",13));
            personList.add(new Person("zhaoliu",15));
            personList.add(new Person("lidamazi",15));
            //list转map age:name
            Map<Integer,String> personMap = personList.stream().collect(Collectors.toMap(Person::getAge,Person::getName,(k1,k2)->k2));
            //list转map age:person
            Map<Integer,Person> personMap2 = personList.stream().collect(Collectors.toMap(Person::getAge, Function.identity(),(k1, k2)->k2));

            //对list进行过滤
            List<Person> selectedList = personList.stream().filter((Person person)->person.getAge()<15).collect(Collectors.toList());

            //对list进行过滤后再转map
            Map<Integer,Person> personMap3 = personList.stream().filter((Person person)->person.getAge()<15).collect(Collectors.toMap(Person::getAge, Function.identity(),(k1, k2)->k2));
    }
}

3 stream流

Employee.java

package com.tangguanlin.lambda;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
 * 作者:汤观林
 * 完成日期:2021年05月04日
 */
@AllArgsConstructor
@Data
public class Employee {

    private int id;
    private int age;
    private String gender;
    private String firstName;
    private String lastName;
}

StreamFilterPredicate.java

package com.tangguanlin.lambda;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/** 
 * stream流
 * 作者:汤观林
 * 完成日期:2021年05月04日
 */
public class StreamFilterPredicate {
    public static void main(String[] args) {
        
        List<String> playerList = Arrays.asList("kobe","james","curry","cyyt");

        //数组,Set,文件都可以转为管道流
       List<String> playerSortedList = playerList.stream()  //list转为管道流
                                                 .filter(s->s.startsWith("c")) //过滤
                                                 .map(String::toUpperCase)    //变成大写
                                                 .sorted()      //排序
                                                 .collect(Collectors.toList());  //流转为list
        //最后结果能转为List,Map,Set
       System.out.println(playerSortedList);
        
        Employee e1 = new Employee(1,23,"M","Rick","Beethovan");
        Employee e2 = new Employee(2,13,"M","Rick","Hengis");
        Employee e3 = new Employee(3,43,"M","Ricky","Martin");
        Employee e4 = new Employee(4,26,"M","Jon","Lowman");
        Employee e5 = new Employee(5,49,"F","Cristine","Maria");
        Employee e6 = new Employee(6,15,"M","David","eezor");
        Employee e7 = new Employee(7,68,"F","Melissa","Roy");
        Employee e8 = new Employee(8,79,"M","Alex","Gussin");
        Employee e9 = new Employee(9,15,"F","Neetu","Singh");
        Employee e10 = new Employee(10,45,"M","Nayeen","Jain");

        List<Employee> employees = Arrays.asList(e1,e2,e3,e4,e5,e6,e7,e8,e9,e10);

        //数组,Set,文件都可以转为管道流

        //1.filter用法
       List<Employee> employees1 = employees.stream()
                 .filter(e->e.getAge()>70&&e.getGender().equals("M"))
                 .collect(Collectors.toList());
           //最后结果能转为List,Map,Set

       //2.map的用法:对每个元素进行处理
        List<Employee> employees2=employees.stream()
                .map(e->{
                    e.setAge(e.getAge()+1);
                    e.setGender(e.getGender().equals("M")?"male":"female");
                    return e;
                })
                .collect(Collectors.toList());

        //3.map+forEach 的用法:对每个元素进行处理  输出每个元素
        employees.stream()
                .map(e->{
                    e.setAge(e.getAge()+1);
                    e.setGender(e.getGender().equals("M")?"male":"female");
                    return e;
                })
                .forEach(e->System.out.println(e.getFirstName()));

        //4.limit 去前几个
        List<Employee> employees3=employees.stream()
                                           .limit(2) //取前2个
                                            .collect(Collectors.toList());

        //5.skip 跳过前几个
        List<Employee> employees4=employees.stream()
                                           .skip(2) //跳过前2个
                                           .collect(Collectors.toList());

        //6.distinct 去重
        List<Employee> employees5 =employees.stream()
                                            .distinct()
                                            .collect(Collectors.toList());
        //7.sorted 排序
        List<Employee> employees6 = employees.stream()
                                             .sorted(Comparator.comparing(Employee::getAge))
                                             .collect(Collectors.toList());


        //8.sort 排序  按年龄倒序排序
        employees.sort(Comparator.comparing(Employee::getGender) //性别倒序
                                 .thenComparingInt(Employee::getAge) //年龄倒序
                                 .reversed() //倒序
                       );

        //9.anyMatch 是否存在(有1个就算)
       boolean isHave =  employees.stream().anyMatch(e->e.getAge()>10);

        //10.allMatch 是否所有的人年龄都大于18
        boolean isHave2 = employees.stream().allMatch(e->e.getAge()>18);

        //11.noneMatch 没有1个 小于18岁的
        boolean isHave3 = employees.stream().noneMatch(e->e.getAge()<18);

        //12.查找 元素
       Optional<Employee> OptionalEmployee = employees.stream()
                                                      .filter(e->e.getAge()>10)
                                                      .findFirst();
       Employee employee7 = OptionalEmployee.get();
    }
}

4 lambda应用场景

Lambda 表达式是 Java 8 引入的新特性,结合 forEach 方法可以更方便地实现遍历。

此外,它还可代替 Runnable 类,大大简化了代码的编写。

下面介绍了一些常见的应用场景,在这些场景中适时地使用 Lambda 表达式要比通常的方式来得更加简洁和方便。

4.1 列表迭代

对一个列表的每一个元素进行操作,不使用 Lambda 表达式时如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
for (int element : numbers) {
    System.out.prinln(element);
}

使用 Lambda 表达式:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(x -> System.out.println(x));

如果只需要调用单个函数对列表元素进行处理,

那么可以使用更加简洁的 方法引用 代替 Lambda 表达式:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(System.out::println);

4.2 事件监听

不使用 Lambda 表达式

button.addActionListener(new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        //handle the event
    }
});

使用 Lambda 表达式,需要编写多条语句时用花括号包围起来:

button.addActionListener(e -> {
    
});

4.3 Predicate接口

java.util.function 包中的 Predicate 接口可以很方便地用于过滤。如果你需要对多个对象进行过滤并执行相同的处理逻辑,那么可以将这些相同的操作封装到 filter 方法中,由调用者提供过滤条件,以便重复使用。

不使用 Predicate 接口,对于每一个对象,都需要编写过滤条件和处理逻辑

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> words = Arrays.asList("a", "ab", "abc");

numbers.forEach(x -> {
    if (x % 2 == 0) {
        //process logic
    }
})
words.forEach(x -> {
    if (x.length() > 1) {
        //process logic
    }
})

使用 Predicate 接口,将相同的处理逻辑封装到 filter 方法中,重复调用:

public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    List<String> words = Arrays.asList("a", "ab", "abc");

    filter(numbers, x -> (int)x % 2 == 0);
    filter(words, x -> ((String)x).length() > 1);
}

public static void filter(List list, Predicate condition) {
    list.forEach(x -> {
        if (condition.test(x)) {
            //process logic
        }
    })
}

filter 方法也可写成:

public static void filter(List list, Predicate condition) {
    list.stream().filter(x -> condition.test(x)).forEach(x -> {
        //process logic
    })
}

4.4 Map映射

使用 Stream 对象的 map 方法将原来的列表经由 Lambda 表达式映射为另一个列表,并通过 collect 方法转换回 List 类型:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> mapped = numbers.stream().map(x -> x * 2).collect(Collectors.toList());
mapped.forEach(System.out::println);

4.5 Reduce聚合

reduce 操作,就是通过二元运算对所有元素进行聚合,最终得到一个结果。例如使用加法对列表进行聚合,就是将列表中所有元素累加,得到总和。

因此,我们可以为 reduce 提供一个接收两个参数的 Lambda 表达式,该表达式就相当于一个二元运算:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce((x, y) -> x + y).get();
System.out.println(sum);

代替 Runnable

以创建线程为例,使用 Runnable 类的代码如下:

Runnable r = new Runnable() {
    @Override
    public void run() {
        //to do something
    }
};
Thread t = new Thread(r);
t.start();

使用 Lambda 表达式:

Runnable r = () -> {
    //to do something
};
Thread t = new Thread(r);
t.start();

或者使用更加紧凑的形式:

Thread t = new Thread(() -> {
    //to do something
});
t.start;

t();
System.out.println(sum);


代替 Runnable

以创建线程为例,使用 Runnable 类的代码如下:

```java
Runnable r = new Runnable() {
    @Override
    public void run() {
        //to do something
    }
};
Thread t = new Thread(r);
t.start();

使用 Lambda 表达式:

Runnable r = () -> {
    //to do something
};
Thread t = new Thread(r);
t.start();

或者使用更加紧凑的形式:

Thread t = new Thread(() -> {
    //to do something
});
t.start;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值