使用Intellij IDEA 解决Java8的数据流问题

杏奴
• 阅读 3720

使用Intellij IDEA 解决Java8的数据流问题

原文:Fixing Java 8 Stream Gotchas with IntelliJ IDEA

译者:飞龙

协议:CC BY-NC-SA 4.0

Java8在2014年三月发布,距离现在(2015年三月五号)快有一年了。我们打算将Pondus的所有生产服务器升级到这一新版本。从那时起,我们将大部分代码库迁移到lambda表达式数据流和新的日期API上。我们也会使用Nashorn来把我们的应用中运行时发生改变的部分变成动态脚本。

除了lambda,最实用的特性是新的数据流API。集合操作在任何我见过的代码库中都随处可见。而且对于那些集合操作,数据流是提升代码可读性的好方法。

但是一件关于数据流的事情十分令我困扰:数据流只提供了几个终止操作,例如reducefindFirst属于直接操作,其它的只能通过collect来访问。工具类Collctors提供了一些便利的收集器,例如toListtoSetjoininggroupingBy

例如,下面的代码对一个字符串集合进行过滤,并创建新的列表:

stringCollection
    .stream()
    .filter(e -> e.startsWith("a"))
    .collect(Collectors.toList());

在迁移了300k行代码到数据流之后,我可以说,toListtoSet、和groupingBy是你的项目中最常用的终止操作。所以我不能理解为什么不把这些方法直接集成到Stream接口上面,这样你就可以直接编写:

stringCollection
    .stream()
    .filter(e -> e.startsWith("a"))
    .toList();

这在开始看起来是个小缺陷,但是如果你需要一遍又一遍地编写这些代码,它会非常烦人。

toArray()方法但是没有toList(),所以我真心希望一些便利的收集器可以在Java9中这样添加到Stream接口中。是吧,Brian?ಠ_ಠ

注:Stream.js是浏览器上的Java 8 数据流API的JavaScript接口,并解决了上述问题。所有重要的终止操作都可以直接在流上访问,十分方便。详情请见API文档

无论如何,IntelliJ IDEA声称它是最智能的Java IDE。所以让我们看看如何使用IDEA来解决这一问题。

使用 IntelliJ IDEA 来帮忙

IntelliJ IDEA自带了一个便利的特性,叫做实时模板(Live Template)。如果你还不知道它是什么:实时模板是一些常用代码段的快捷方式。例如,你键入sout并按下TAB键,IDEA就会插入代码段System.out.println()。更多信息请见这里

如何用实时模板来解决上述问题?实际上我们只需要为所有普遍使用的默认数据流收集器创建我们自己的实时模板。例如,我们可以创建.toList缩写的实时模板,来自动插入适当的收集器.collect(Collectors.toList())

下面是它在实际工作中的样子:

使用Intellij IDEA 解决Java8的数据流问题

构建你自己的实时模板

让我们看看如何自己构建它。首先访问设置(Settings)并在左侧的菜单中选择实时模板。你也可以使用对话框左上角的便利的输入过滤。

使用Intellij IDEA 解决Java8的数据流问题

下面我们可以通过右侧的+图标创建一个新的组,叫做Stream。接下来我们向组中添加所有数据流相关的实时模板。我经常使用默认的收集器toListtoSetgroupingByjoin,所以我为每个这些方法都创建了新的实时模板。

这一步非常重要。在添加新的实时模板之后,你需要在对话框底部指定合适的上下文。你需要选择Java → Other,然后定义缩写、描述和实际的模板代码。

// Abbreviation: .toList
.collect(Collectors.toList())

// Abbreviation: .toSet
.collect(Collectors.toSet())

// Abbreviation: .join
.collect(Collectors.joining("$END$"))

// Abbreviation: .groupBy
.collect(Collectors.groupingBy(e -> $END$))

特殊的变量$END$指定在使用模板之后的光标位置,所以你可以直接在这个位置上打字,例如,定义连接分隔符。

提示:你应该开启"Add unambiguous imports on the fly"(自动添加明确的导入)选项,便于让IDEA自动添加java.util.stream.Collectors的导入语句。选项在Editor → General → Auto Import中。

让我们在实际工作中看看这两个模板:

连接

使用Intellij IDEA 解决Java8的数据流问题

分组

使用Intellij IDEA 解决Java8的数据流问题

Intellij IDEA中的实时模板非常灵活且强大。你可以用它来极大提升代码的生产力。你知道实时模板可以拯救生活的其它例子吗?请让我知道

仍然不满意吗?在我的数据流教程中学习所有你想要学到的东西。

祝编程愉快!

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Wesley13 Wesley13
4年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Stella981 Stella981
4年前
MacOS VSCode 安装 GO 插件失败问题解决
0x00问题重现Installinggolang.org/x/tools/cmd/guruFAILEDInstallinggolang.org/x/tools/cmd/gorenameFAILEDInstallinggolang.org/x/lint/golintFAILEDInst
Stella981 Stella981
4年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
4年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Easter79 Easter79
4年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa