java 8 stream特性
在Java 8的新功能特性中,最棒的特性就是允许我们去表达我们想要完成什么而不是要怎样做。这正是循环的不足之处。要确保循环的灵活性是需要付出代价的。return、break 或者 continue都会显著地改变循环的实际表现。这迫使我们不仅要清楚我们要实现怎样的代码,还要了解循环是怎样工作的。
在介绍Java 8的流(Stream)时,我们学会了一些集合操作的实用技巧。现在我们要看看怎样把这些循环转换为更简洁,可读性更高的代码。
开始编码!
好吧,讲的够多了,是时候展示一些例子了!
这次我们要以文章为例子。一篇文章拥有一个标题,一个作者和几个标签。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
private class Article { private final String title; private final String author; private final List<String> tags; private Article(String title, String author, List<String> tags) { this .title = title; this .author = author; this .tags = tags; } public String getTitle() { return title; } public String getAuthor() { return author; } public List<String> getTags() { return tags; } } |
每个例子都会包含一个使用传统循环的方案和一个使用Java 8新特性的方案。
在第一个例子里,我们要在集合中查找包含“Java”标签的第一篇文章。
看一下使用for循环的解决方案。
1
2
3
4
5
6
7
8
9
10
|
public Article getFirstJavaArticle() { for (Article article : articles) { if (article.getTags().contains( "Java" )) { return article; } } return null ; } |
现在我们使用Stream API的相关操作来解决这个问题。
1
2
3
4
5
|
public Optional<Article> getFirstJavaArticle() { return articles.stream() .filter(article -> article.getTags().contains( "Java" )) .findFirst(); } |
是不是很酷?我们首先使用 filter 操作去找到所有包含Java标签的文章,然后使用 findFirst() 操作去获取第一次出现的文章。因为Stream是“延迟计算”(lazy)的并且filter返回一个流对象,所以这个方法仅在找到第一个匹配元素时才会处理元素。
现在,让我们获取所有匹配的元素而不是仅获取第一个。
首先使用for循环方案。
1
2
3
4
5
6
7
8
9
10
11
12
|
public List<Article> getAllJavaArticles() { List<Article> result = new ArrayList<>(); for (Article article : articles) { if (article.getTags().contains( "Java" )) { result.add(article); } } return result; } |
使用Stream操作的方案。
1
2
3
4
5
|
public List<Article> getAllJavaArticles() { return articles.stream() .filter(article -> article.getTags().contains( "Java" )) .collect(Collectors.toList()); } |
在这个例子里我们使用 collection 操作在返回流上执行少量代码而不是手动声明一个集合并显式地添加匹配的文章到集合里。
到目前为止还不错。是时候举一些突出Stream API强大的例子了。
根据作者来把所有的文章分组。
照旧,我们使用循环方案。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public Map<String, List<Article>> groupByAuthor() { Map<String, List<Article>> result = new HashMap<>(); for (Article article : articles) { if (result.containsKey(article.getAuthor())) { result.get(article.getAuthor()).add(article); } else { ArrayList<Article> articles = new ArrayList<>(); articles.add(article); result.put(article.getAuthor(), articles); } } return result; } |
我们能否找到一个使用流操作的简洁方案来解决这个问题?
1
2
3
4
|
public Map<String, List<Article>> groupByAuthor() { return articles.stream() .collect(Collectors.groupingBy(Article::getAuthor)); } |
很好!使用 groupingBy 操作和 getAuthor 方法,我们得到了更简洁、可读性更高的代码。
现在,我们查找集合中所有不同的标签。
我们从使用循环的例子开始。
1
2
3
4
5
6
7
8
9
10
|
public Set<String> getDistinctTags() { Set<String> result = new HashSet<>(); for (Article article : articles) { result.addAll(article.getTags()); } return result; } |
好,我们来看看如何使用Stream操作来解决这个问题。
1
2
3
4
5
|
public Set<String> getDistinctTags() { return articles.stream() .flatMap(article -> article.getTags().stream()) .collect(Collectors.toSet()); } |
棒极了!flatmap 帮我把标签列表转为一个返回流,然后我们使用 collect 去创建一个集合作为返回值。
一切皆有可能
以上的就是如何使用可读性更高的代码代替循环的例子。务必仔细看看Stream API,因为这篇文章仅仅提到它的一些皮毛而已。
更新
收到solarfuse和dhruvgairola的评论后,更新了getDistinctTags()例子,使用集合(Set)作为返回集合。
原文链接: deadcoderising 翻译: ImportNew.com- 进林
译文链接: http://www.importnew.com/14841.html
[ 转载请保留原文出处、译者和译文链接。]
关于作者: 进林
java 8 stream特性的更多相关文章
- Java 8新特性之Stream(八恶人-3)
“You John Ruth The Hangman” 绞刑者鲁斯·约翰 “When the Hangman catches you, you hang.”当被绞刑者抓住了,你肯定会被绞死 一.基本介 ...
- Java 8新特性之旅:使用Stream API处理集合
在这篇“Java 8新特性教程”系列文章中,我们会深入解释,并通过代码来展示,如何通过流来遍历集合,如何从集合和数组来创建流,以及怎么聚合流的值. 在之前的文章“遍历.过滤.处理集合及使用Lambda ...
- Java 8 新特性-Stream更优雅的处理集合入门
Java 8 新特性之--Stream 一. 简单介绍 Stream是Java 8提出了的一种新的对集合对象功能的增强.它集合Lambda表达式,对集合提供了一些非常便利,高效的操作,使得代码具有非常 ...
- Java 8 新特性之 Stream 流基础体验
Java 8 新特性之 Stream 流基础体验 package com.company; import java.util.ArrayList; import java.util.List; imp ...
- 再来看看Java的新特性——Stream流
半年前开始试着使用Java的新特性,给我印象最深的就是Stream流和Optional.其中Stream提高了看法效率,让代码看起来十分清爽. 为什么要使用流? 摘要中已经说明了,为了提高开发效率.流 ...
- Java 8新特性(二):Stream API
本篇文章继续介绍Java 8的另一个新特性--Stream API.新增的Stream API与InputStream和OutputStream是完全不同的概念,Stream API是对Java中集合 ...
- Java 8 新特性:Lambda、Stream和日期处理
1. Lambda 简介 Lambda表达式(Lambda Expression)是匿名函数,Lambda表达式基于数学中的λ演算得名,对应于其中的Lambda抽象(Lambda Abstract ...
- Java 8新特性:新语法方法引用和Lambda表达式及全新的Stream API
新语法 方法引用Method references Lambda语法 Lambda语法在AndroidStudio中报错 Stream API 我正参加2016CSDN博客之星的比赛 希望您能投下宝贵 ...
- 3分钟看完Java 8——史上最强Java 8新特性总结之第二篇 Stream API
目录 · 概况 · 切片(Slicing) · 映射(Mapping) · 匹配(Matching) · 查找(Finding) · 归约(Reducing) · 排序(Sorting) · 数值流( ...
随机推荐
- 前端Datatables自定义事件(监听Datatables插件一些常见的事件动作)
今天开发项目的时候,用Datatables插件做前端分页列表,想在列表发生翻页.排序.搜索.改变单页显示数据条数这些行为的时候做一些其他的操作,看了半天Datatables官网终于找到可以监测到这些事 ...
- HttpClient-----待补充
1.简介 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 java.net 包中 ...
- Wireshark、Netcat
Wireshark Wireshark是一个网络数据包分析软件,功能是截取网络数据包,并尽可能显示出最为详细的网络数据包数据.为了安全考虑,wireshark只能查看封包,而不能修改封包的内容,或者发 ...
- Ubuntu系统无法获得锁/var/lib/dpkg/lock - open (11: 资源暂时不可用)的解决方案
Ubuntu系统无法获得锁/var/lib/dpkg/lock - open (11: 资源暂时不可用)的解决方案 问题 使用Ubuntu打开终端时,输入带有sudo apt-get 命令行是 ...
- vim/sed/awk/grep等文件批处理总结
Vim相关操作 1.基础 * 和 # 对对当前光标所在的单词进行搜索 %匹配括号移动,包括 (, {, [ K 查看man手册 ga 查看ascii值 g CTRL-G 统计字数,使用Visual模式 ...
- C# listbox DataSource数据绑定--一年半以前的bug
listbox使用DataSource进行数据绑定和删除,大家肯定都会, 写这个随笔只是因为....这是一年半以前刚进公司的我遗留的bug,现在看看当时竟然没有解决 - - 现在写个测试程序,写个随笔 ...
- 处理javabean的JSP标签
(1) 关于javabean要求: 1,具有无参的构造函数. 2,针对每一个成员变量,因改提供相应get/set. 3,implments Serializable(实现才能对象序列化). (2) 使 ...
- 数据包发包工具bittwist
数据包发包工具bittwist 渗透测试中,通过发送特定格式的包,可以实施网络嗅探和攻击.Kali Linux提供一款发包工具bittwist.该工具可以通过指定的网络接口发送数据.该工具不仅可以 ...
- API网关的设计思路及落地 IT大咖说 - 大咖干货,不再错过
API网关的设计思路及落地 IT大咖说 - 大咖干货,不再错过 http://www.itdks.com/dakashuo/new/dakalive/detail/1407
- MSDN WinUSB Example
The WinUSB user-mode library uses device interface classes to communicate with the kernel-mode USB s ...