Java基础知识:Lambda表达式

2022-08-05 19:09:41 浏览数 (1)

Lambda表达式

其实Lambda并不能算作Java基础内容更应该归类为Java简化开发原则,因为懒得开新专辑了所以就一并放在Java基础知识中整理掉。 本文将按照不同Lambda语法种类进行整理。

基本概念

Lambda 表达式是 Java 在 JDK 8 中引入的一种新的语法元素和操作符(操作符为“->”,也称Lambda操作符或箭头操作符)它将 Lambda 分为两个部分:

  1. 左侧:小括号内 指定了 Lambda 表达式需要的 形参列表;
  2. 右侧:大括号内 指定了 Lambda 体,是抽象方法的实现逻辑,也是 Lambda 表达式要执行的功能。

对于形参列表:

  1. 空参需要提供小括号:() -> {}
  2. 单个参数可以省略小括号:e -> {}
  3. 参数类型可省略,编译器会进行类型推断

对于Lambda体:

  1. 可以包含多行代码、可以 return:() -> {return null;};
  2. 单行代码可省略{}:() -> System.out.println("Hello, World!");
  3. 有返回值且只返回为单行代码可以不写return和{}:(x,y) -> Integer.compare(x,y);
代码语言:javascript复制
//使用Lambda表达式遍历HashMap中的键值对
HashMap.forEach((k,v) -> {
	System.out.println("key = "   k   " value = "   v);
}); //注意此处的分号
//使用Lambda表达式处理线程接口
Runnable r1 = () -> System.out.println("Hello, World!");
//保留数据类型
Consumer<String> con = (String str) -> {System.out.print(str);};
//省略数据类型
Consumer<String> con = (str) -> {System.out.print(str);};
//拥有返回值
Comparator<Integer> com = (x,y) -> {
	System.out.print("returned success");
	return Integer.compare(x,y);
};
//拥有返回值且为返回值为单语句
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);

方法引用

方法引用是函数式接口的一个实例,通过方法的名字来指向一个方法。当需要传递给Lambda体进行操作且有已经实现了的方法,就可以使用方法引用。语法如下:

代码语言:javascript复制
类或对象名::方法名

包括如下3种情况:

代码语言:javascript复制
对象::非静态方法
类::静态方法
类::非静态方法
  1. 针对第一第二种情况要求:接口中抽象方法的形参列表 和 返回值类型 与 方法引用中的形参列表 和 返回值类型 保持一致
  2. 针对第三种情况要求:当函数式接口方法的第一个参数是 需要引用方法 的调用者,并且第二个参数是 需要引用方法 的参数(或无参数)时,使用ClassName::methodName

对象::new

对象::new 语法是 JDK8 以后新增的 Lambda 表达式一部分的内容,它主要用于实例化一个静态的对象模型。

代码语言:javascript复制
public class demo {
  public static void main(String[] args) {
    //第一种方式
    ICar iCar1 = new ICar() {
      @Override
      public Car getCar(String name, Integer money) {
        return new Car(name, money);
      }
    };
    System.out.println(iCar1.getCar("凯迪拉克", 30));
 
    //第二种方式
    ICar iCar2 = (name, money) -> new Car(name, money);
    Car car = iCar2.getCar("凯迪拉克", 30);
    System.out.println(car.toString());
 
    //第三种方式
    ICar iCar3 = Car::new;
    Car car3 = iCar3.getCar("凯迪拉克", 30);
    System.out.println(car3);
  }
}
 
@FunctionalInterface
interface ICar {
  Car getCar(String name, Integer money);
}
 
class  Car{
  private String name;
  private Integer money;
 
  public Car(String name, Integer money) {
    this.name = name;
    this.money = money;
  }
 
  public String getName() {
    return name;
  }
 
  public void setName(String name) {
    this.name = name;
  }
 
  public Integer getMoney() {
    return money;
  }
 
  public void setMoney(Integer money) {
    this.money = money;
  }
 
  @Override
  public String toString() {
    return "Car{"  
        "name='"   name   '''  
        ", money="   money  
        '}';
  }
}

Stream API

  • Stream关注的是对数据的运算,与CPU打交道
  • 集合关注的是数据的存储,与内存打交道
  • 从 JDK8 开始,提供了一套API,使用这套API可以对内存中的数据进行过滤、排序、映射、归约等操作(类似于sql对数据库中表的相关操作)。

Stream流的注意点:

① Stream 自己不会存储元素。 ② Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。 ③ Stream 操作是同步执行的。这意味着他们会等到需要结果的时候才执行

Stream流的中间操作:

  1. 筛选与切片

方法

描述

filter(Predicate p)

接受Lambda从流中排除一些元素。

distinct()

筛选,通过流产生元素的hashCode()和equals()方法去除重复元素。

limit(long maxSize)

截断流,使其元素数量不超过给定数量。

skip(long n)

跳过元素,返回一个去除了前n个元素的新的流。若流中元素不足n个,则返回一个空的流。与截断流互补。

  1. 映射

方法

描述

map(Function f)

接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

map ToDouble(ToDoubleFunction f)

接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。

map ToInt(ToIntFunction f)

接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。

map ToLong(ToLongFunction f)

接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。

flatMap(Function f)

接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个新的流。

  1. 排序

方法

描述

sorted()

产生一个新流,其中按自然顺序排序。

sorted(Comparator com)

产生一个新流,其中按比较器顺序排序。

Stream流的终止操作:

  1. 匹配与查找

方法

描述

allMatch(Predicate p)

检查是否匹配所有元素

anyMatch(Predicate p)

检查是否至少匹配一个元素

noneMatch(Predicate p)

检查是否没有匹配所有元素

findFirst()

返回第一个元素

findAny()

返回当前流中的任意元素

  1. 归约

方法

描述

count()

返回流中元素总数

max(Comparator c)

返回流中最大值

min(Comparator c)

返回流中最小值

forEach(Comsumer c)

内部迭代(使用Collection接口,需要用户去做迭代,称为外部迭代,而Stream API使用内部迭代)

  1. 收集

方法

描述

collect(Collector c)

将流转换为其他形式。接收一个 Collector 接口的实现方法,用于给 Stream 中元素做汇总操作。

Stream流的Collectors:

方法

返回类型

作用

toList

List<T>

把流中的元素收集到List中

List<Employee> emps = list.stream().collect(Collectors.toList());

toSet

Set<T>

把流中的元素收集到Set中

Set<Employee> emps = list.stream().collect(Collectors.toSet());

toCollection

Collection<T>

把流中的元素收集到List中

Collection<Employee> emps = list.stream().collect(Collectors.toCollection());

0 人点赞