Lambda表达式、Stream流学习随笔

Lambda表达式是java8中最重要的新功能之一。使用Lambda表达式可以替换只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁易懂。Lambda表达式同时还提升了对集合、框架的迭代、遍历、过滤数据的操作。

 

原理的数组排序:

 

public class LambdaDemo {
    /**
     * 自定义比较器,根据字符串排序
     * @param args
     */
    public static void main(String[] args) {
        List list = Arrays.asList("java", "javascript", "php", "python");
        Collections.sort(list, new Comparator() {
            @Override
            public int compare(String o1, String o2) {
                return o1.length() - o2.length();
            }
        });
        System.out.println(list);
    }
}

 

现在Lambda表达式:

/**
 * Lambda表达式的数组排序
 * @param args
 */
public static void main(String[] args) {
    List list = Arrays.asList("java", "javascript", "php", "python");
    Collections.sort(list, Comparator.comparingInt(String::length));
    list.forEach(System.out::print);
}

Lambda表达式特点:

  1. 函数式编程
  2. 参数类型自动推断
  3. 代码量少、简洁

 

 

Lambda表达式应用场景:

  • 任何有函数式接口的地方

 

函数式接口:

  • 简单来说,只有一个抽象方法的接口就属于函数式接口(加@FunctionalInterface注解不会报错的接口)

 

函数式接口类型:

(1)功能性接口:Function

(2)断言性接口:Predicate

(3)供给性接口:Supplier

(4)消费性接口:Consumer

介绍:

函数式接口

参数类型

返回类型

用途

Consumer

T

void

对类型T参数操作,无返回结果,包含方法 void accept(T t)

Supplier

T

返回T类型参数,方法时 T get()

Function

T

R

对类型T参数操作,返回R类型参数,包含方法 R apply(T t)

Predicate

T

boolean

断言型接口,对类型T进行条件筛选操作,返回boolean,包含方法 boolean test(T t)

 

 通过函数式接口类型的返回值或者参数类型,对应表达式的参数和返回值,可以决定表达式的写法。

 

表达式案例:

()->{}    
()->{System.out.println("aaa");}    // 表示没有参数,没有返回值,方法体一行代码
()->System.out.println("aaa")     // 等价于上一个,因为方法只有一行代码可以省略{}
(a)->System.out.println(a)     // 等价于上一个,因为方法只有一行代码可以省略{},消费性接口:Consumer
()->{return 100}      // 抽象方法没有参数,有一个int返回值,供给性接口:Supplier的表示类型
()->return 100      // 抽象方法没有参数,有一个int返回值,等价于上一个
(int x)->{return x+1;}    // 抽象方法有一个int参数,返回一个int值,参数类型可以省略,如下
(x)->x+1      // 表示方法需要一个参数,返回一个int类型
x->x+1
(a)->return  a.length()   // 返回值和传入值的类型不同,功能性接口:Function

 

方法引用:

  1. 含义:方法引用就是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,如果抽象方法的实现恰好可以使用调用另外一个方法来实现,就有可能可以使用方法引用;idea有提示只要ctrl + entry,就会自动校正。
  2. 分类:静态方法引用(类名::staticMethod)、实例方法引用(inst::instMethod)、对象方法引用(类名::instMethod)、构造方法引用(类名::new)Lambda表达式、Stream流学习随笔_第1张图片

  • 静态方法引用:如果函数式接口的实现恰好可以通过调用一个静态方法来实现,那么就可以使用静态方法引用
  • 实例方法引用:如果函数式接口的实现恰好可以通过调用一个实例的方法来实现,那么久可以使用实例方法引用
  • 对象方法引用:抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当作实例方法的参数,如果函数时接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用。
  • 构造方法引用:如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用

Stream :

是一组用来处理数组、集合的API

 

Stream 特性:

  1. 不是数据结构,没有内部存储
  2. 不支持索引访问
  3. 延迟计算
  4. 支持并行
  5. 很容易生成数组或集合
  6. 支持过滤、查找、转换、汇总、聚合等操作

 Lambda表达式、Stream流学习随笔_第2张图片

filter、collect:

返回过滤后的结果,收集成为一个新的集合。打印新集合

List list = Arrays.asList(1, 2, 3, 4, 5);
List collect = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
collect.forEach(System.out::println);

 

sum:

将流的元素求和

List list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.stream().filter(x -> x % 2 == 0).mapToInt(x->x).sum();
System.out.println(sum);

max:

求出流最大值

List list = Arrays.asList(1, 2, 3, 4, 5);
Optional max = list.stream().max((a, b) -> a - b);
System.out.println(max.get()); 

findAny/findFirst:

从流中取值(随机取值/取第一个值)

List list = Arrays.asList(1, 2, 3, 4, 5);
Optional any = list.stream().findAny();
Optional first = list.stream().findFirst();
System.out.println(any);
System.out.println(first);

sorted:

排序

List list = Arrays.asList(1, 2, 3, 4, 5);
Stream sorted = list.stream().sorted();   // 自然排序
Stream mySorted = list.stream().sorted((a,b)->b-a);   // 从小到大排序

distinct:

去重

List list = Arrays.asList(1, 2, 3, 4, 5, 5, 3, 6, 2);
list.stream().distinct().forEach(System.out::println);

 

 

你可能感兴趣的:(java)