Heim  >  Artikel  >  Java  >  Detaillierte Erklärung von Lambda und Stream in Java8 (mit Code)

Detaillierte Erklärung von Lambda und Stream in Java8 (mit Code)

不言
不言nach vorne
2018-10-16 14:42:593869Durchsuche

Dieser Artikel bietet Ihnen eine detaillierte Erklärung von Lambda und Stream in Java8 (mit Code). Ich hoffe, dass er für Freunde hilfreich ist.

1. Einführung

In diesem Artikel werden hauptsächlich die beiden wichtigsten neuen Funktionen von Java8 vorgestellt: Lambda-Ausdruck und Stream-API. Die beiden bieten ein höheres Abstraktionsniveau und vereinfachen die Entwicklung ., Verbesserung der Produktionseffizienz.

2. Lambda-Ausdruck

2.1 Erste Einführung in den Lambda-Ausdruck

Erstellen Sie einen Thread und verwenden Sie eine Runnableanonyme innere Klasse

Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello Aron.");
            }
        });

Es scheint kein großes Problem zu sein, aber tatsächlich liegen die Nachteile auf der Hand: Es gibt zu viele Vorlagensyntaxen und die einzigen Anweisungen mit wirklicher Geschäftsbedeutung sind System.out.println("Hello Aron.")Aus diesem Grund stört es auch ernsthaft unsere Lesart des Codes.

Nachdem Sie den Lambda-Ausdruck eingeführt haben, können Sie so schreiben

Thread thread = new Thread(() -> System.out.println("Hello Aron."));

Es ist zu prägnant, haben Sie eine Idee?

2.2 Weitere Lambda-Ausdrücke

 Runnable runnable = () -> System.out.println("Hello World.");
 Consumer<T> tConsumer = bean -> System.out.println("Hello World.");
 Runnable runnable1 = () -> {
         System.out.println("Hello World.");
         System.out.println("Hello World.");
     };

Die Syntax ist in 3 Abschnitte unterteilt: Parameter, -> und Anweisungen, also (...)-> { ...}

2.3 Funktionsschnittstelle

Java ist eine stark typisierte Sprache und Methodenparameter haben feste Typen. Hier liegt also das Problem. Wenn Lambda-Ausdrücke als eine Reihe von Codefragmenten betrachtet werden, kann diese Absicht vorerst auch als funktionale Schnittstelle verstanden werden.

Beim Programmieren werden Sie immer auf viele funktionale Schnittstellen stoßen. Im Folgenden sind einige der wichtigsten funktionalen Schnittstellen im JDK aufgeführt

Beispiele für Schnittstellenparameter-Rückgabetypen

接口 参数 返回类型 示例
Predicate T boolean 值等于“Hello”吗?
Consumer T void 输出一个值
Function T R 获取对象的一个属性
Supplier None T 工厂方法
UnaryOperator T T 逻辑非(!)
BinaryOperator (T, T) T 求2个数的和(+)

2.4 类型推断

先看一段熟悉的集合代码

ArrayList<Java8Test> list = new ArrayList<>();

在ArrayList中申明了存储的元素的类型,于是在ArrayList<>()这里的类型可以缺省,编译器可以根据左侧(即上文)推断出来。

同理,在lambda表达式也是一样的。

BinaryOperator<Long> addLongs = (x, y) -> x + y;

在上面的表达 式中,我们注意到 (x, y)这里是没有申明方法的参数类型的,却能执行数学运算 +

这里根据函数接口指定的泛型类为Long,即可推断方法的参数为Long,然后执行x + y

2.5 Lambda小结

Lambda表达式是一个匿名方法,简化了匿名内部类的写法,把模板语法屏蔽,突出业务语句,传达的更像一种行为。

Lambda表达式是有类型的,JDK内置了众多函数接口

Lambda的3段式结构:(...)-> { ...}

3. Stream 流

3.1 简介

流(Stream)是Java8的新特性,是一种使程序员得以站在更高的抽象层次上对集合进行操作。在思路上,类似于SQL的存储过程,有几个步骤:

  1. 先定义一些操作的集合,注意:这里只定义,不真正执行

  2. 触发执行,获取结果

  3. 对结果进一步处理,筛选、打印、使用

其中,第1步的定义操作叫惰性求值,给你套路(返回Stream),但是不会执行返回结果。

第2步的触发操作叫及早求值,这个人说干就干,立马要结果(返回结果数据)。

第3步的筛选类似SQL的where子句,对结果进一步的筛选。

3.2 Stream API

Stream 类位于java.util.stream包,是Java8核心的类之一,拥有众多方法,下面罗列了一些比较重要的方法进行讲解。更多的是抛砖引玉,任何教程都比不上自己的悟性来得爽快,先找点感觉,先掌握基本用法尝试使用起来,慢慢自然就会了。

3.2.1 Stream.of(T… t)

要使用Stream,那就必须得先创建一个String类型的Stream

Stream<String> StrStream = Stream.of("a", "b");

3.2.2 Stream.collect(Collector collector)

使用收集器CollectorStrStream转化为熟悉的集合Collection

 List<String> collect = StrStream.collect(Collectors.toList());

3.2.2 Stream.map(Function mapper)

所谓map,从字面理解就是映射。这里指的是对象关系的映射,

比如从对象集合映射到属性结合:

List<String> names = Stream.of(new Student("zhangSan"), new Student("liSi"))
                        .map(student -> student.getName())
                        .collect(toList());

从小写字母映射到大写字母:

List<String> collected = Stream.of("a", "b", "hello")
                        .map(string -> string.toUpperCase())
                        .collect(toList());

将 字符串流 根据空格分割成 字符串数组流

Stream<String> stringStream = Stream.of("Hello Aron.");
Stream<String[]> stringArrayStream = stringStream.map(word -> word.split(" "));

3.2.3 Stream.filter(Predicate predicate)

filter顾名思义,过滤筛选。这里的参数函数接口是一个条件,筛选出满足条件的元素

// 筛选年龄大于19的学生
List<Student> stu = Stream.of(new Student("zhangSan", 19), new Student("liSi"), 20)
                        .filter(student -> student.getAge() > 19)
                        .collect(toList());

3.2.4 Stream.flatMap(Function> mapper)

flatMap扁平化映射,即将数据元素为数组的Stream转化为单个元素

Stream<String> stringStream = Stream.of("Hello Aron.");
// 返回值为数组
Stream<String[]> stringArrayStream = stringStream.map(word -> word.split(" "));
// flatMap扁平化映射后,元素都合并了
Stream<String> flatResult = stringArrayStream.flatMap(arr -> Arrays.stream(arr))

3.2.5 Stream.max(Comparator comparator)

max即最大,类似SQL中的函数max(),从数据中根据一定的条件筛选出最值

// 筛选年龄最大/小的学生
Stream<Student> studentStream = Stream.of(new Student("zhangSam", 19), new Student("liSi", 20));
Optional<Student> max = studentStream.max(Comparator.comparing(student -> student.getAge()));
// Optional<Student> max = studentStream.min(Comparator.comparing(student -> student.getAge()));
// 年龄最大/小的学生
Student student = max.get();

3.2.7 Sream.reduce(T identity, BinaryOperator binaryOperator)

reduce操作实现从一组值中生成一个值,上面的maxmin实际上都是reduce操作。

参数Identity 表示初始值,

参数binaryOperator是一个函数接口,表示二元操作,可用于数学运算

// 使用reduce() 求和 (不推荐生产环境使用)
int count = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);

上面代码,展开reduce() 操作

BinaryOperator<Integer> accumulator = (acc, element) -> acc + element;
int count = accumulator.apply( accumulator.apply(accumulator.apply(0, 1),2), 3);

3.2.8 综合操作

// 查找所有姓张的同学并按字典顺序排序,存储到list
List<Student> newList = studentList.Stream()
            .filter(student -> student.getName().startsWith("张"))
            .sorted(Comparator.comparing(student -> student.getName())
            .collect(toList());

Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung von Lambda und Stream in Java8 (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen