Java 8 流教程
Java 8 中引入的 Stream API 用于处理对象集合。流是一系列支持各种方法的对象,这些方法可以通过流水线来产生所需的结果。在进一步讨论之前,让我们讨论一下 Collection 和 Streams 之间的区别,以了解为什么引入这个概念。
Note:
- If we want to represent a group of objects as a single entity then we should go for collection.
- But if we want to process objects from the collection then we should go for streams.
如果我们想使用流的概念,那么 stream() 是要使用的方法。 Stream 可用作接口。
Stream s = c.stream();
在上面的前置标签中,“c”指的是集合。所以在集合上,我们调用了stream() 方法,同时我们将它存储为 Stream 对象。从今以后,我们将通过这种方式获取 Stream 对象。
Note: Streams are present in java’s utility package named java.util.stream
现在让我们从流中涉及的基本组件开始。它们如下所列:
- 元素序列
- 来源
- 聚合操作
- 流水线
- 内部迭代
Java流的特点?
- 流是不是一个数据结构,而不是它需要从类别,阵列,或I / O通道的输入。
- Streams 不会改变原始数据结构,它们仅根据流水线方法提供结果。
- 每个中间操作都被延迟执行并作为结果返回一个流,因此可以将各种中间操作流水线化。终端操作标记流的结束并返回结果。
在继续讨论这个概念之前,先考虑一个例子,其中我们有一个整数 ArrayList,我们假设我们应用一个过滤器来只从插入的对象中获取偶数。
Stream 如何在内部工作?
在溪流中,
- 为了从对象中过滤掉,我们有一个名为filter()的函数
- 为了强加条件,我们确实有一个谓词逻辑,它只是一个功能接口。这里函数接口可以用随机表达式代替。因此,我们可以直接在我们的谓词中强加条件检查。
- 为了收集元素,我们将使用Collectors.toList()来收集所有必需的元素。
- 最后,我们将这些元素存储在一个列表中,并在控制台上显示输出。
例子
Java
// Java Program to illustrate FILTER & COLLECT Operations
// Importing input output classes
import java.io.*;
// Importing utility class for List and ArrayList classes
import java.util.*;
// Importing stream classes
import java.util.stream.*;
// Main class
public class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating an ArrayList object of integer type
ArrayList al = new ArrayList();
// Inserting elements to ArrayList class object
// Custom input integer numbers
al.add(2);
al.add(6);
al.add(9);
al.add(4);
al.add(20);
// First lets print the collection
System.out.println("Printing the collection : "
+ al);
// Printing new line for better output readability
System.out.println();
// Stream operations
// 1. Getting thr stream from this collection
// 2. Filtering out only even elements
// 3. Collecting the required elements to List
List ls
= al.stream()
.filter(i -> i % 2 == 0)
.collect(Collectors.toList());
// Print the collection after stream operation
// as stored in List object
System.out.println(
"Printing the List after stream operation : "
+ ls);
}
}
Java
// Java program to illustrate Intermediate Operations
// in Streams
// Importing required classes
import java.io.*;
import java.util.*;
import java.util.stream.*;
// Main class
class Test {
// Main driver method
public static void main(String[] args)
{
// Creating an integer Arraylist to store marks
ArrayList marks = new ArrayList();
// These are marks of the students
// Considering 5 students so input entries
marks.add(30);
marks.add(78);
marks.add(26);
marks.add(96);
marks.add(79);
// Printing the marks of the students before grace
System.out.println(
"Marks of students before grace : " + marks);
// Now we want to grace marks by 6
// using the streams to process over processing
// collection
// Using stream, we map every object and later
// collect to List
// and store them
List updatedMarks
= marks.stream()
.map(i -> i + 6)
.collect(Collectors.toList());
// Printing the marks of the students after grace
System.out.println(
"Marks of students after grace : "
+ updatedMarks);
}
}
Printing the collection : [2, 6, 9, 4, 20]
Printing the List after stream operation : [2, 6, 4, 20]
输出说明:在我们的集合对象中,我们使用 add() 操作输入了元素。在处理通过流存储它们的对象后,我们在流的谓词中强加一个条件以仅获取偶数元素,我们根据我们的要求获取对象中的元素。因此,流以这种方式帮助我们处理过度处理的集合对象。
Streams 上的各种核心操作?
大致上有 3 种类型的操作可以通过流进行,如下图所示:
- 中间操作
- 终端操作
- 短路操作
让我们在此仅通过示例来讨论特定深度的流中的中间操作,以便通过理论手段找出其他操作。因此,有 3 种类型的中间操作,如下所示:
- 操作一: filter()方法
- 操作2: map()方法
- 操作 3: sorted() 方法
所有这三个都在下面讨论,因为它们在几乎大多数场景中都是齐头并进的,并且稍后通过在下面的干净Java程序中实现它们来提供更好的理解。正如我们在上面的例子中已经研究过的,我们试图过滤处理过的对象可以解释为 filter() 操作对流进行操作。稍后,从处理过的对象过滤元素中,我们使用收集器将元素收集回 List,我们在 Collectors.toList() 方法的帮助下为其导入了一个名为Java.util.stream的特定包。这在流中被称为 collect() 操作,所以在这里我们不会再举一个例子来单独讨论它们。
例子:
Java
// Java program to illustrate Intermediate Operations
// in Streams
// Importing required classes
import java.io.*;
import java.util.*;
import java.util.stream.*;
// Main class
class Test {
// Main driver method
public static void main(String[] args)
{
// Creating an integer Arraylist to store marks
ArrayList marks = new ArrayList();
// These are marks of the students
// Considering 5 students so input entries
marks.add(30);
marks.add(78);
marks.add(26);
marks.add(96);
marks.add(79);
// Printing the marks of the students before grace
System.out.println(
"Marks of students before grace : " + marks);
// Now we want to grace marks by 6
// using the streams to process over processing
// collection
// Using stream, we map every object and later
// collect to List
// and store them
List updatedMarks
= marks.stream()
.map(i -> i + 6)
.collect(Collectors.toList());
// Printing the marks of the students after grace
System.out.println(
"Marks of students after grace : "
+ updatedMarks);
}
}
Marks of students before grace : [30, 78, 26, 96, 79]
Marks of students after grace : [36, 84, 32, 102, 85]
Note: For every object if there is urgency to do some operations be it square, double or any other than only we need to use map() function operation else try to use filter() function operation.
现在,极客们很清楚“为什么”引入流,但您应该想知道“在哪里”使用它。答案很简单,因为我们在日常生活中确实经常使用它们。因此,用简单的话来说,极客直接将 p 放在集合概念适用的地方,流概念可以在那里应用。
现实生活中的例子
示例 1:通常,在日常生活中,每当从数据库中获取数据时,我们更有可能使用集合,因此必须应用流本身的概念来处理处理过的数据。
现在我们将讨论实时示例以将我们生活中的流相互关联。在这里,我们将采用最广泛使用的,即如下:
- 杂货店中的流媒体
- 移动网络中的流
示例 2:杂货店中的流
上面已经提供的图形图像是在流中实现的,如下所示:
List transactionsIds =
transactions.stream()
.filter(t -> t.getType() == Transaction.GROCERY)
.sorted(comparing(Transaction::getValue).reversed())
.map(Transaction::getId)
.collect(toList());
示例 3:移动网络中的流
同样,我们可以采用另一个广泛使用的概念,即我们处理我们的手机号码。在这里,我们不会提出列表,而只是展示全球各种服务提供商如何在移动网络中调用流概念。
Collection can hold any number of object so let ‘mobileNumber’ be a collection and let it be holding various mobile numbers say it be holding 100+ numbers as objects. Suppose now the only carrier named ‘Airtel’ whom with which we are supposed to send a message if there is any migration between states in a country. So here streams concept is applied as if while dealing with all mobile numbers we will look out for this carrier using the filter() method operation of streams. In this way, we are able to deliver the messages without looking out for all mobile numbers and then delivering the message which senses impractical if done so as by now we are already too late to deliver. In this way these intermediate operations namely filter(), collect(), map() help out in the real world. Processing becomes super simpler which is the necessity of today’s digital world.
希望现在你的用户开始意识到Java中流的力量,就好像我们必须做同样的任务,我们需要映射对应于每个对象,增加代码长度,降低我们代码的最优性。通过使用流,我们可以在一行中处理对象中包含的元素,就像我们正在处理对象本身的流概念一样。
Note: filter, sorted, and map, which can be connected together to form a pipeline.