ホームページ  >  記事  >  Java  >  Java8のLambdaとStreamを詳しく解説(コード付き)

Java8のLambdaとStreamを詳しく解説(コード付き)

不言
不言転載
2018-10-16 14:42:593869ブラウズ

この記事では Java8 の Lambda と Stream について詳しく説明しています (コード付き)。必要な方は参考にしていただければ幸いです。

1. はじめに

この記事では主に、Java8 の 2 つの主な新機能、ラムダ式とストリーム API を紹介します。この 2 つは、より高いレベルの抽象化を提供し、開発を簡素化します。 。 、生産性を高める。

2. Lambda 式

2.1 Lambda 式の最初の概要

スレッドを作成し、Runnableanonymous を使用します。 class

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

は大きな問題ではないように思えるかもしれませんが、実際には欠点が非常に明らかです。テンプレート構文が多すぎて、実際にビジネス上重要なステートメントは System.out.println だけです。 (「こんにちは、アーロン。」) は、このため、コードを読むのに重大な支障をきたします。

ラムダ式を導入すると、次のように書くことができます

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

簡潔すぎるのですが、何かアイデアはありますか?

2.2 その他のラムダ式

 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.");
     };

構文は、パラメーター、->、ステートメント、つまり (...) の 3 つのセクションに分かれています。 - > { ...}

2.3 関数インターフェイス

Java は厳密に型指定された言語であり、メソッドのパラメータには固定型があります。ここで問題が発生します。ラムダ式も、コードの断片の集まりとみなした場合、この意図は、当面は関数型インターフェースとして理解できます。

プログラミングの過程では、常に多くの関数インターフェイスに遭遇します。以下は、JDK の最も重要な関数インターフェイスの一部です。

インターフェイス パラメーターの戻り値の型の例です。

#述語< ;T> ;Tboolean 値は「Hello」と同じですか? #ConsumerFunctionSupplierUnaryOperatorBinaryOperator

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());

インターフェース パラメータ 戻り値の型
T void 値を出力
T R オブジェクトのプロパティを取得
None T ファクトリ メソッド
T T 論理否定 (!)
(T, T) T 2 つの数値の合計を求めます ( )

以上がJava8のLambdaとStreamを詳しく解説(コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。