saz 发表于 2021-11-19 13:28

Java8 lambda表达式 笔记

# Lambda表达式

**`()-> {}`**: 本质是一种**`匿名函数`**,实现一个***函数式接口***,

---

## 基础语法规则

### 箭头符号

`->`         lambda运算符

### 箭头左侧

```tex
- 若无参数列表,箭头符号左侧写小括号
- 单个参数,可以省略小括号
- 多个参数,必须加上小括号
- 多个参数,可以不写参数类型;若要写,则全部要写。不推荐写参数类型;
```

### 箭头右侧

```tex
- 只有一条语句,可以省略大括号;有返回可以省略 `return`
- 右侧有多条语句,必须写大括号;有返回必须写`return`
```

## 操作员工的进化

### 准备

#### 员工类

```java
class Employee{
      private int id;
      private String name;
      private double salary;
      private int age;
    // 省略 constructor Setter getter toString
}
```

#### 员工列表

```java
List<Employee> employees = new ArrayList<Employee>(){{
    add(new Employee(1,"SA ZHANG",3500D,23));
    add(new Employee(2,"SI LI",4500D,23));
    add(new Employee(3,"WU WANG",6000D,24));
    add(new Employee(4,"LIU ZHAO",9000D,25));
    add(new Employee(5,"QI A",9000D,35));
}};
```

### 筛选排序

#### 传统艺能

**重写compareTo()方法,指定排序字段和规则**

缺点:**下次换个字段排序或者换个筛选条件,玩完。**

#### 设计模式-策略模式

**讲排序做成接口,为每一个策略提供一个实现类**,实现类中,只有一行代码不一样

​        优点:符合开闭原则,可以灵活适应变更需求

​        缺点:相似代码大量冗余,每一个策略都得加一个实现类

#### lambda

```java
@Test
public void test03(){
    Collections.sort(employees,(e1,e2)-> {
      if (e1.getAge() == e2.getAge()){
            return Double.compare(e1.getSalary(),e2.getSalary());
      }else {
            return Integer.compare(e1.getAge(),e2.getAge());
      }
    });

    for (Employee employee : employees) {
      System.out.println(employee);
    }
}
```

#### Stream API

```java
employees.stream().sorted((e1,e2)-> e1.getAge() -e2.getAge()).forEach(System.out::println);
```

## 内置四大函数式接口

### Interface Consumer<T>

​                **消费型接口,表示接受单个输入参数并且不返回结果的操作。**

​                与大多数其他功能界面不同,Consumer预计将通过副作用进行操作

```java
void accept(T) // 传递参数
```

```java
@Test
public void testConsumer(){
    happy(100D,(m) -> System.out.println("白嫖失败,支付【" + m + "】元"));
}

// 单参无返回
void happy(double money, Consumer<Double> consumer){
    consumer.accept(money);
}
```

### Interface Supplier<T>

​        **供给型接口,代表结果供应商**

```
// 无参有返回
T get() //获得结果。
```

```java
@Test
public void testSupplier(){
    List<Integer> integers = proNum(10, () -> (int) (Math.random() * 100));
    for (Integer integer : integers) {
      System.out.print(integer + "\t");
    }
}

// 无参有返回
List<Integer> proNum(int num, Supplier<Integer> supplier){
    // 产生指定个数的整数,放到集合返回出去
    List<Integer> nums = new ArrayList<>();
    for (int i = 0; i < num; i++) {
      nums.add(supplier.get());
    }
    return nums;
}
```

### Interface Function<T,R>

**函数型接口,接受一个参数并产生结果的函数**

```java
R apply(T t) // 将此函数应用于给定的参数
```

```java
@Test
public void testFunction(){
    String upper = strOperation("int the end - link park",str -> str.toUpperCase());
    System.out.println(upper);
}

// 单参有返回
String strOperation(String str, Function<String,String > function){
    return function.apply(str);
}
```

### Interface Predicate<T>

**断言型接口,表示一个参数的谓词(布尔值函数)**

```java
boolean test(T t) // 在给定的参数上评估这个谓词
```

```java
@Test
public void testPrediction(){
    List<Integer> list = Arrays.asList(1,3,5,8,3,1,2);
    List<Integer> res1 = filter(list,integer -> integer >= 5);
    print(res1);
    List<Integer> res2 = filter(list,integer -> integer <= 2);
    print(res2);
}

// 单参返回
List<Integer> filter(List<Integer> list, Predicate<Integer> predicate){
    List<Integer> resList = new ArrayList<>();
    for (Integer integer : list) {
      // 应用的时候指定过滤操作
      boolean test = predicate.test(integer);
      if (test){
            resList.add(integer);
      }
    }
    return resList;
}

// 打印
void print(List<Integer> list){
    for (Integer re : list) {
      System.out.print(re + "\t");
    }
    System.out.println();
}
```

SMQAQWO 发表于 2021-11-19 14:47

感谢分享

xiaocai66 发表于 2021-11-19 16:16

学习到了,感谢

zhangsubao 发表于 2021-11-22 16:40

感谢分享学习了
页: [1]
查看完整版本: Java8 lambda表达式 笔记