Understanding Java 8 Streams API---reference
http://java.amitph.com/2014/01/understanding-java-8-streams-api.html
Since past few versions, Java has started giving importance to concurrency. Java 8 goes one more step ahead and has developed a Streams API which lets us think about parallelism. Nowadays, because of the tremendous amount of development on the hardware front, multicore CPUs are becoming more and more general. In order to leverage the hardware capabilities Java had introduced Fork Join Framework. Java 8 Streams API supports many parallel operations to process the data, while completely abstracting out the low level multithreading logic and letting the developer fully concentrate on the data and the operations to be performed on the data.
Most of us know, parallel processing is all about dividing a larger task into smaller sub tasks (forking), then processing the sub tasks in parallel and then combining the results together to get the final output (joining). Java 8 Streams API provides a similar mechanism to work with Java Collections. The Java 8 Streams concept is based on converting Collections to a Stream, processing the elements in parallel and then gathering the resulting elements into a Collection.
Collections vs Streams:
Collections are in-memory data structures which hold elements within it. Each element in the collection is computed before it actually becomes a part of that collection. On the other hand Streams are fixed data structures which computes the elements on-demand basis.
The Java 8 Streams can be seen as lazily constructed Collections, where the values are computed when user demands for it. Actual Collections behave absolutely opposite to it and they are set of eagerly computed values (no matter if the user demands for a particular value or not).
Deeper Look at Streams:
The Stream interface is defined in java.util.stream package. Starting from Java 8, the java collections will start having methods that return Stream. This is possible because of another cool feature of Java 8, which is default methods. Streams can be defiled as a sequence of elements from a source that supports aggregate operations.
The source here refers to a Collection, IO Operation or Arrays who provides data to a Stream. Stream keeps the order of the data as it is in the source.
Just like functional programming languages, Streams support Aggregate Operations. The common aggregate operations are filter, map, reduce, find, match, sort. These operations can be executed in series or in parallel.
The Streams also support Pipelining and Internal Iterations. The Java 8 Streams are designed in such a way that most of its stream operations returns Streams only. This help us creating chain of various stream operations. This is called as pipelining. The pipelined operations looks similar to a sql query.
In Java, we traditionally use for loops or iterators to iterate through the collections. These kind of iterations are called asexternal iterations and they are clearly visible in the code. Java 8 Stream operations has methods like foreach, map, filter, etc. which internally iterates through the elements. The code is completely unaware of the iteration logic in the background. These kind of iterations are called as internal iterations.
List<String> names =newArrayList<>();
for(Student student : students){
if(student.getName().startsWith("A")){
names.add(student.getName());
}
}
There is nothing special about this code. This is a traditional Java external iterations example. Now, have a look at the below code. This line is doing exactly the same thing but we can't see any iteration logic here and hence it is called asinternal iterations.
List<string> names = students.stream().map(Student::getName).filter(name->name.startsWith("A"))
.collect(Collectors.toList());
Operations on Streams:
There are variety of operations defined in the Streams interface. Have a look at the below example. Here we are iterating through list of students, and selecting names of first 10 students whose names start with "A".
List<String> names = students.stream()
.map(Student::getName)
.filter(name->name.startsWith("A"))
.limit(10)
.collect(Collectors.toList());
In the above code there are few operations like map, filter, limit, and collect. We can categories these operations into Intermediate operations and Terminal Operations.
The intermediate operations return streams and hence can be connected together to form a pipeline of operations. In above example map, filter, and limit are such intermediate operations.
The terminal operations, as the name suggests reside at the end of such a pipeline and their task is to close the stream in some meaningful way. Terminal operations collect the results of various stream operations in the form of anything like lists, integers or simply nothing. If we have to print the name of students whose name starts with "A", the foreach operation will be our terminal operation that will print all the names from the filtered stream and will return nothing.
The most interesting part to know about the intermediate operations is that they are lazy. The intermediate operations will not be invoked until the terminal operation is invoked. This is very important when we are processing larger data streams. The process only on demand principle drastically improves the performance. The laziness of theintermediate operations help to invoke these operation in one pass. Now, if you are not clear with single pass, please wait until we dive into more details about Java 8 Streams during our subsequent discussions.
Numerical Ranges:
Most of the times we need to perform certain operation on the numerical ranges. To help in such scenarios Java 8 Streams API has come up with three useful interfaces IntStream, DobuleStream, and LongStream.
IntStream.rangeClosed(1,10).forEach(num ->System.out.print(num));
// ->12345678910
IntStream.range(1,10).forEach(num ->System.out.print(num));
// ->123456789
All of the above mentioned interfaces support range and rangeClosed methods. range method is exclusive whilerangeClosed is inclusive.
Both of these methods return stream of numbers and hence can be used as intermediate operations in a pipeline.
Building Streams:
By now, we have had a quick overview of what is Java 8 Stream and how useful it is. We have seen Java Collections can generate streams of the data contained within them, we have also seen how to get streams of numerical ranges. But creating Streams is not limited to this, there are many other ways by which streams can be generated.
Using the 'Of' method we can created stream of hardcoded values. Suppose we want stream of hardcoded Strings, just pass all of the Strings to the 'of' method.
Suppose we want to create a stream of all the elements in an array, we can do so by calling stream method on Arrays. Arrays is a traditional utility class which now has a support for stream methods.
//Creating Stream of hardcoded Strings and printing each String
Stream.of("This","is","Java8","Stream").forEach(System.out::println);
//Creating stream of arrays
String[] stringArray =newString[]{"Streams","can","be","created","from","arrays"};
Arrays.stream(stringArray).forEach(System.out::println);
//Creating BufferedReader for a file
BufferedReader reader =Files.newBufferedReader(Paths.get("File.txt"),StandardCharsets.UTF_8);
//BufferedReader's lines methods returns a stream of all lines
reader.lines().forEach(System.out::println);
Recently added NIO API as well as the traditional IO API have been updated to support the streams. This provides very useful abstraction of directly creating streams of lines being read from a file.
Java 8 Streams is a completely new to Java and it is a very large concept, and it is difficult to cover it completely on this platform. That doesn't mean our discussion on streams ends here. Till now we have seen what are the Java 8 Streams, how the existing APIs have been updated to support Streams, brief about various methods on streams, and how to build streams.
We will keep this discussion alive in subsequent posts. We are yet to look more inside streams, various intermediate stream operations, and ways of collecting computed data with the help of various terminal operations. Thanks!
Understanding Java 8 Streams API---reference的更多相关文章
- Java 8 Streams API 详解
流式编程作为Java 8的亮点之一,是继Java 5之后对集合的再一次升级,可以说Java 8几大特性中,Streams API 是作为Java 函数式的主角来设计的,夸张的说,有了Streams A ...
- [转]深入理解Java 8 Lambda(类库篇——Streams API,Collectors和并行)
以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-l ...
- Java 9 揭秘(18. Streams API 更新)
Tips 做一个终身学习的人. 在本章中,主要介绍以下内容: 在Stream接口中添加了更加便利的方法来处理流 在Collectors类中添加了新的收集器(collectors) JDK 9中,在St ...
- 深入理解Java 8 Lambda(类库篇——Streams API,Collectors和并行)
转载:http://zh.lucida.me/blog/java-8-lambdas-inside-out-library-features/ 关于 深入理解 Java 8 Lambda(语言篇——l ...
- Java 8 集合之流式(Streams)操作, Streams API 详解
因为当时公司的业务需要对集合进行各种各样的业务逻辑操作,为了提高性能,就用到了这个东西,因为以往我们以前用集合都是需要去遍历(串行),所以效率和性能都不是特别的好,而Streams就可以使用并行的方式 ...
- Java 8 中的 Streams API 详解
为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...
- Java 8中的 Streams API 详解
为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...
- (转)Java 8 中的 Streams API 详解
为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...
- Java 8 Stream API Example Tutorial
Stream API Overview Before we look into Java 8 Stream API Examples, let’s see why it was required. S ...
随机推荐
- 解决"要执行请求的操作,WordPress需要访问您网页服务器的权限"
比如我们在VPS主机中创建WordPress站点的时候,会有需要在线安装主题.插件等,但是点击下载安装的时候会有"要执行请求的操作,WordPress需要访问您网页服务器的权限. 请输入您的 ...
- asp.netcore+jenkins+docker+svn+centos7.2 持续集成,每天凌晨获取最新代码打包发布
运行环境: centos7.2服务器或则虚拟机 可以是腾讯云也可以是内网服务器,(如果是内网服务器需要用frp做内网穿透,这样才可以通过外网访问该服务器) svnserver 来托管代码 一.安装je ...
- F - ACboy needs your help again! (模拟)
ACboy was kidnapped!! he miss his mother very much and is very scare now.You can't image how dark th ...
- OOP1(定义基类和派生类)
面向对象程序设计基于三个基本概念:数据抽象,继承和动态绑定 数据抽象是一种依赖于接口和实现分离的编程技术.继承和动态绑定对程序的编号有两方面的影响:一是我们可以更容易地定义与其它类相似但不完全相同的类 ...
- loj #2508. 「AHOI / HNOI2018」游戏
#2508. 「AHOI / HNOI2018」游戏 题目描述 一次小 G 和小 H 在玩寻宝游戏,有 nnn 个房间排成一列,编号为 1,2,…,n,相邻房间之间都有 111 道门.其中一部分门上有 ...
- [51nod1236] 序列求和 V3(斐波那契数列)
题面 传送门 题解 把求和的柿子用斐波那契数列的通项公式展开 \[ \begin{aligned} Ans &=\sum\limits_{i = 1}^{n} \left(\frac{(\fr ...
- 洛谷P3236 [HNOI2014]画框(最小乘积KM)
题面 传送门 题解 我似乎连\(KM\)都不会打啊→_→ 和bzoj2395是一样的,只不过把最小生成树换成\(KM\)了.因为\(KM\)跑的是最大权值所以取个反就行了 //minamoto #in ...
- Java面向对象之内部类(访问格式)
一.基础概念 1.内部类是定义在类中的类.A类需要直接访问B类中的成员时,可以将A类定义到B类中,作为B类的内部类存在. 2.内部类可以相当于外部类中的一个成员,可以被成员修饰符所修饰.(如:publ ...
- 选择排序 思想 JAVA实现
已知一个数组 9.29.95.47.79.37.18.56.96.22 使用选择排序是数组有序 选择排序同样是一个运行时间为O(N²)的排序算法. 算法思想:(以从小到大为例) 9.29.95.47. ...
- Anya and Cubes 搜索+map映射
Anya loves to fold and stick. Today she decided to do just that. Anya has n cubes lying in a line an ...