流是聚合操作(filter()、map()、forEach() 和 collect())的有序管道,用于处理(概念上无界的)元素序列。流管道由一个源和零个或多个中间操作组成;和终端操作。聚合操作执行一个函数。理想情况下,流中函数的输出仅取决于其输入参数。流不包含非瞬态阶段。每个流的工作原理基本相同,即:
- 从数据源开始。
- 通过中间操作管道处理数据。
- 以终端操作结束。
默认情况下,流中的每个聚合操作都按顺序运行其函数,即在调用者的控制线程中一个接一个地运行。流可以从集合、列表、集合、整数、长整数、双精度数、数组、文件行创建。
流操作要么是中间的,要么是终端的。过滤、映射或排序等中间操作返回一个流,因此我们可以链接多个中间操作。诸如 forEach、collect 或 reduce 之类的终端操作要么为空,要么返回非流结果。流在Java引入了函数式编程,并从Java 8 开始支持Java 8 流是 PQSA1 管道和过滤器模式的实现。
例子:
Java
// Java Program to Compare Streams to Loops
// Importing required libraries
import java.io.IOException;
import java.lang.String;
import java.nio.file.*;
import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.*;
// Main class
// JavaStreams
class GFG {
// Main driver method
public static void main(String[] args)
throws IOException
{
// 1. Integer Stream
System.out.println("Integer Stream : ");
IntStream.range(1, 10).forEach(System.out::print);
// New line
System.out.println();
// 2. Integer Stream with skip
System.out.println("Integer Stream with skip : ");
IntStream.range(1, 10).skip(5).forEach(
x -> System.out.println(x));
// New line
System.out.println();
// 3. Integer Stream with sum
System.out.println("Integer Stream with sum : ");
System.out.println(IntStream.range(1, 5).sum());
// New line
System.out.println();
// 4. Stream.of, sorted and findFirst
System.out.println(
"Stream.of, sorted and findFirst : ");
Stream.of("Java ", "Scala ", "Ruby ")
.sorted()
.findFirst()
.ifPresent(System.out::println);
// New line
System.out.println();
// 5. Stream from Array, sort, filter and print
String[] names = { "AI", "Matlab",
"Scikit", "TensorFlow",
"OpenCV", "DeepLearning",
"NLP", "NeuralNetworks",
"Regression" };
System.out.println(
"Stream from Array, sort, filter and print : ");
Arrays
.stream(names) // same as Stream.of(names)
.filter(x -> x.startsWith("S"))
.sorted()
.forEach(System.out::println);
// New line
System.out.println();
// 6. average of squares of an int array
System.out.println(
"Average of squares of an int array : ");
Arrays.stream(new int[] { 2, 4, 6, 8, 10 })
.map(x -> x * x)
.average()
.ifPresent(System.out::println);
// New line
System.out.println();
// 7. Stream from List, filter and print
// Display message only
System.out.println(
"Stream from List, filter and print : ");
List people = Arrays.asList(
"AI", "Matlab", "Scikit", "TensorFlow",
"OpenCV", "DeepLearning", "NLP",
"NeuralNetworks");
people.stream()
.map(String::toLowerCase)
.filter(x -> x.startsWith("a"))
.forEach(System.out::println);
// New line
System.out.println();
// 8. Reduction - sum
// Display message only
System.out.println("Reduction - sum : ");
double total
= Stream.of(7.3, 1.5, 4.8)
.reduce(0.0,
(Double a, Double b) -> a + b);
// Print and display
System.out.println("Total = " + total);
System.out.println();
// 9. Reduction - summary statistics
System.out.println(
"Reduction - summary statistics : ");
IntSummaryStatistics summary
= IntStream.of(7, 2, 19, 88, 73, 4, 10)
.summaryStatistics();
// Print and display
System.out.println(summary);
System.out.println();
}
}
Java
// Java Program to Comparing Streams to Loops
// Importing utility packages
import java.util.*;
// Class 1
// helper class
class ProgrammingLanguage {
// Member variables of this class
int rank;
String name;
int value;
// Member method of this class
public ProgrammingLanguage(int rank, String name,
int value)
{
// this keyword is used to reger current object
// itself
this.rank = rank;
this.name = name;
this.value = value;
}
}
// Class 2
// JavaStreamExample
public class GFG {
// MAin driver method
public static void main(String[] args)
{
// Creating an object of List class
// Declaring object of user defined type (above
// class)
List programmingLanguage
= new ArrayList();
// Adding elements to the object of this class
// Custom input entries
programmingLanguage.add(
new ProgrammingLanguage(1, "Java", 7000));
programmingLanguage.add(
new ProgrammingLanguage(2, "Rust", 2000));
programmingLanguage.add(
new ProgrammingLanguage(3, "Ruby", 1500));
programmingLanguage.add(
new ProgrammingLanguage(4, "Scala", 2500));
programmingLanguage.add(
new ProgrammingLanguage(5, "Groovy", 4000));
// Creating object of List class of integer type
List languageValueList
= new ArrayList();
// For each loops for iteration
for (ProgrammingLanguage language :
programmingLanguage) {
// Filtering data of List
if (language.value < 3000) {
// Adding price to above elements
languageValueList.add(language.value);
}
}
// Print and display al elements inside the object
System.out.println(languageValueList);
}
}
Integer Stream :
123456789
Integer Stream with skip :
6
7
8
9
Integer Stream with sum :
10
Stream.of, sorted and findFirst :
Java
Stream from Array, sort, filter and print :
Scikit
Average of squares of an int array :
44.0
Stream from List, filter and print :
ai
Reduction - sum :
Total = 13.600000000000001
Reduction - summary statistics :
IntSummaryStatistics{count=7, sum=203, min=2, average=29.000000, max=88}
现在,讨论循环以找出结论性差异。循环是Java中的一项功能,它有助于执行一组指令,直到控制布尔表达式的计算结果为 false。提供了不同类型的循环以满足任何编程需要。每个循环都有自己的目的和适合的用例。
例子:
Java
// Java Program to Comparing Streams to Loops
// Importing utility packages
import java.util.*;
// Class 1
// helper class
class ProgrammingLanguage {
// Member variables of this class
int rank;
String name;
int value;
// Member method of this class
public ProgrammingLanguage(int rank, String name,
int value)
{
// this keyword is used to reger current object
// itself
this.rank = rank;
this.name = name;
this.value = value;
}
}
// Class 2
// JavaStreamExample
public class GFG {
// MAin driver method
public static void main(String[] args)
{
// Creating an object of List class
// Declaring object of user defined type (above
// class)
List programmingLanguage
= new ArrayList();
// Adding elements to the object of this class
// Custom input entries
programmingLanguage.add(
new ProgrammingLanguage(1, "Java", 7000));
programmingLanguage.add(
new ProgrammingLanguage(2, "Rust", 2000));
programmingLanguage.add(
new ProgrammingLanguage(3, "Ruby", 1500));
programmingLanguage.add(
new ProgrammingLanguage(4, "Scala", 2500));
programmingLanguage.add(
new ProgrammingLanguage(5, "Groovy", 4000));
// Creating object of List class of integer type
List languageValueList
= new ArrayList();
// For each loops for iteration
for (ProgrammingLanguage language :
programmingLanguage) {
// Filtering data of List
if (language.value < 3000) {
// Adding price to above elements
languageValueList.add(language.value);
}
}
// Print and display al elements inside the object
System.out.println(languageValueList);
}
}
[2000, 1500, 2500]
By far we have understood both of the concepts and come across to know they don’t go hand in hand, one has advantage over other as per the usage where it is to be used. Hence, wrapping off the article by illustrating their advantages which are as follows:
流的优势
- Streams 是一种更具声明性的风格。或者更具表现力的风格。
- 流与函数有很强的亲和力。 Java 8 引入了 lambda 表达式和函数式接口,这打开了一个包含强大技术的完整工具箱。流提供了将函数应用于对象序列的最方便和自然的方式。
- 流鼓励较少的可变性。这有点与函数式编程方面有关,即我们使用流编写的程序类型往往是我们不修改对象的程序类型。
- 流鼓励松散耦合。我们的流处理代码不需要知道流的来源或其最终终止方法。
- 流可以简洁地表达相当复杂的行为。
循环的优点
- 性能:通过数组的 for 循环在堆和 CPU 使用方面都非常轻量级。如果原始速度和内存节俭是优先事项,则使用流会更糟。
- 熟悉度:世界上到处都是经验丰富的程序程序员,他们来自不同的语言背景,对他们来说循环很熟悉,流很新颖。在某些环境中,您希望编写这类人熟悉的代码。
- 认知开销:由于其声明性质,并且对底层发生的事情的抽象性增加,您可能需要构建一个新的代码与执行相关的思维模型。实际上,您只需要在出现问题时,或者需要深入分析性能或细微错误时才需要这样做。当它“正常工作”时,它就正常工作。
- 调试器正在改进,但即使是现在,当我们在调试器中单步执行流代码时,它也比等效循环更难工作,因为简单循环非常接近传统调试器使用的变量和代码位置。
结论:
如果你有一个小名单;如果你有一个很大的列表,for 循环会表现得更好;并行流会表现得更好。并且由于并行流有相当多的开销,因此不建议使用这些,除非您确定这些开销是值得的。