1. Java 8 的创新:函数式编程

随着 Java 8 的发布,该语言获得了对函数式编程的强大支持。您甚至可以说它获得了期待已久的函数式编程支持。编码变得更快,尽管代码更难阅读🙂

在学习Java函数式编程之前,我们建议您了解三件事:

  1. OOP、继承和接口(Java 核心任务中的级别 1-2)。
  2. 接口中的默认方法实现
  3. 内部类匿名类

消息是您不必知道所有这些就可以使用 Java 中函数式编程的许多特性。坏消息是,如果不了解匿名内部类,将很难准确理解一切是如何安排的以及一切是如何工作的。

在接下来的课程中,我们将重点介绍使用 Java 的函数式编程功能是多么容易和简单,而无需深入了解其工作原理。

理解 Java 函数式编程的所有细微差别需要几个月的时间。您可以在几个小时内学会阅读此类代码。所以我们建议从小处着手。即使是 I/O 流。


2. I/O流:流管道

您还记得曾几何时您学习过 I/O 流:InputStreamOutputStreamReader等等吗Writer

有从数据源读取数据的流类,例如FileInputSteam,还有从其他流读取数据的中间数据流,例如InputStreamReaderBufferedReader

这些流可以组织成数据处理管道。例如,像这样:

FileInputStream input = new FileInputStream("c:\\readme.txt");
InputStreamReader reader = new InputStreamReader(input);
BufferedReader buff = new BufferedReader(reader);

String text = buff.readLine();

重要的是要注意,在前几行代码中,我们只是在构建一个Stream对象链。数据还没有通过管道。

但是一旦我们调用该buff.readLine()方法,就会发生以下情况:

  1. 对象BufferedReader调用对象read()上的方法InputStreamReader
  2. 对象InputStreamReader调用对象read()上的方法FileInputStream
  3. 对象开始从文件中FileInputStream读取数据

换句话说,在我们开始调用read()or之类的方法之前,数据不会沿着流管道移动readLine()。仅仅构建流管道并不能驱动数据通过它。流本身不存储数据。他们只读别人的书。

集合和流

从 Java 8 开始,可以使用流从集合中读取数据(而不仅仅是从集合中读取数据)。但这还不是最有趣的事情。实际上,轻松简单地构建复杂的数据流链成为可能。这样做,以前需要 5-10 行的代码现在可以用 1-2 行编写。

在字符串列表中查找最长字符串的示例:

寻找最长的字符串
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max((s1, s2)-> s1.length()-s2.length()).get();
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Stream<String> stream = list.stream();
Optional<String> optional = stream.max((s1, s2)-> s1.length()-s2.length());
String max = optional.get();

3.Stream界面

Java 8 对流的扩展支持是使用Stream<T>接口实现的,其中T是一个类型参数,表示流中传递的数据类型。换句话说,流完全独立于它传递的数据类型。

要从集合中获取流对象,只需调用其stream()方法即可。代码大致如下所示:

Stream<Type> name = collection.stream();
从集合中获取流

在这种情况下,集合将被视为流的数据源,对象Stream<Type>将是一个以数据流的形式从集合中获取数据的工具。

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Stream<String> stream = list.stream();

顺便说一句,您不仅可以从集合中获取流,还可以从数组中获取流。为此,您需要使用该方法。例如:Arrays.stream()

Stream<Type> name = Arrays.stream(array);
从数组中获取流

在这种情况下,数组将被视为名为 的的数据源name

Integer[] array = {1, 2, 3};
Stream<Integer> stream = Arrays.stream(array);

Stream<Type>创建对象时不会移动任何数据。为了开始构建流管道,我们只是简单地获取了一个流对象。