Javase8 Stream和Lambda表达式

目录

Lambda的产生

Java 语法糖

Lambda 表达式的结构

Lambda语法

什么是功能接口 

什么是Stream?

获取流 

流操作

 中间操作

终端操作


Lambda的产生

        java是面向对象语言,除了部分简单数据类型,Java 中的一切都是对象, 即使数组也是一种对象,每个类创建的实例也是对象。

        在 Java 中定义的函数或 方法不可能完全独立,也不能将方法作为参数或返回一个方法给实例。

        Lambda 表达式是一个匿名函数,我们可以把 lambda 表达式理解为一段可以传递的代码(将代码段像数据一样传递),Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。

Lambda 表达式的本质只是一个 "语法糖" ,由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。

Java 语法糖

语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。Java 中最常用的语法糖主要有泛型、变长参数、条件编译、自动拆装箱、内部类等。虚拟机并不支持这些语法,它们在编译阶段就被还原回了简单的基础语法结构,这个过程成为解语法糖。

Lambda 表达式的结构

Lambda语法

lambda 表达式的语法格式如下:

(parameters) -> expression 或 (parameters) ->{ statements; }

以下是lambda表达式的重要特征:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 无参数,无返回值,
    lambda 体中只有一行代码时,
    {}可以忽略
    () -> System.out.println("Hello World");
    无参数,有返回值
    () -> { return 3.1415 };
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。

Lambda表达式的参数可以是0个1个或多个。

Lambda参数可以显式声明,编译器也可以自动从上文到下文推断如:(int a,int b)和(a,b) 

参数用小括号括起来,用逗号分隔。例如 (a, b) 或 (int a, int b) 或 (String a, int b, float c)。当有且仅有一个参数时,如果不显式指明类型,则不必使用小括号。例如 a -> return a*a。

有参数,无返回值
(String s) -> { System.out.println(s); }
有一个参数,无返回值
s -> { System.out.println(s); }
有多个参数,有返回值
(int a, int b) -> { return a + b; }
有多个参数,表达式参数类型可以不写,
jvm 可以根据上下文进行类型推断
(a, b) -> { return a - b; }

什么是功能接口 

Lambda 表达式只支持函数式接口 也就是只有一个抽象方法的接口.功能接口是 java 8 中的新增功能,它们只允许一个抽象方法。这些接口也称为单抽象方法接口。Java 8 也引入了一个注释,即@FunctionalInterface,当你注释的接口违反了 Functional Interface 的契约时,它可以用于编译器级错误。

即:功能接口不过是带有一个抽象方法的接口,如果在增加一个抽象方法,那么就会报错(编译时错误)

@FunctionalInterface//表示是一个功能函数接口,接口中只能定义一个抽象方法
public interface Oper {

      //使用lambda表达式接口中,只能有一个抽象方法,因为需要自动类型推断
      int add(int a, int b);

}

什么是Stream?

        Stream 是 Java8 的新特性,它允许你以声明式的方式处理数据集合,可以把它看作是遍历数据集的高级迭代器。此外与 stream 与 lambada 表达示结合后编码效率与大大提高,并且可读性更强。
注意 : java8 中的 stream 与 InputStream 和 OutputStream 是完全不同的概念.
它提供了对相关数据集合进行操作的相关办法,我们只需要声明式的告诉其应该做什么
java中的集合,数组主要是存储数据,stream主要作用是对集合进行操作
数据集合->Stream->filter->Stream->sorted->流->tolist/sum/max--->result

            获取流                      中间操作                           终端操作

语法: 

  public static void main(String[] args) {

        Integer[] array = {4, 2, 1, 3, 1, 5, 6, 8, 7};

        Arrays.stream(array) //返回一个Stream对象
                .distinct()
                .filter((e) -> {
                    return e < 6;
                })  //对流进行一个过滤操作,又返回一个流对象
                .sorted((a, b) -> {
                    return a - b;
                }) //对流进行一个排序操作,又返回一个流对象
                .skip(0) //跳过指定数量的元素
                .limit(2) //限制取出的个数
                .forEach((e) -> {
                    System.out.println(e);
                });


    }

获取流 

使用Collection接口下的Stream()

List<String> list = new ArrayList<>();
 Stream<String> stream = list.stream();

使用 Arrays 中的 stream() 方法,将数组转成流

Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);
使用 Stream 中的静态方法:of()
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
使用 BufferedReader.lines() 方法,将每行内容转成流
BufferedReader reader=new BufferedReader(new FileReader("stream.txt")); 
Stream<String> lineStream = reader.lines();

流操作

举个栗子:
List<Apple> apples = applestore
                                   .stream() 获得流
                                   .filter(a -> a.getColor().equals("red")) 中间操作
                                   .collect(Collectors.toList()); 终端操作
流操作:中间操作和终端操作,中间操作会返回另外一个流,终端操作会关闭流,构建一个新的数据集合对象(也可以不构建)

 中间操作

filter:过滤流中的某些元素,
sorted(): 自然排序,流中元素需实现 Comparable 接口
distinct: 去除重复元素
limit(n): 获取 n 个元素
skip(n): 跳过 n 元素,配合 limit(n)可实现分页
map(): 将其映射成一个新的元素

终端操作

forEach: 遍历流中的元素
toArray:将流中的元素倒入一个数组
Min:返回流中元素最小值
Max:返回流中元素最大值
count:返回流中元素的总个数
Reduce:所有元素求和
anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足条件则返回 true,否则返回 false
allMatch:接收一个 Predicate 函数,当流中每个元素都符合条件时才返回 true,否则返回 false
findFirst:返回流中第一个元素
collect:将流中的元素倒入一个集合,Collection 或 Map

猜你喜欢

转载自blog.csdn.net/weixin_56800176/article/details/125864081