Java SE 8:标准库增强

Lambda表达式是Java SE 8的核心功能,大部分的改进都围绕lambda表达式展开。(Jigsaw项目已经被推迟到Java SE 9。)关于lambda表达式的内容,已经在上一篇文章中进行了说明。这篇文章主要介绍Java SE 8中包含的其他Java标准库的增强。

并行排序

随着多核CPU的流行,Java平台的标准库实现也尽可能利用底层硬件平台的能力来提高性能。Java SE 7中引入了Fork/Join框架作为一个轻量级的并行任务执行引擎。Java SE 8把Fork/Join框架用到了标准库的一些方法的实现中。比较典型的是java.utils.Arrays类中新增的parallelSort方法。与已有的sort方法不同的是,parallelSort方法使用Fork/Join框架来实现。在多核CPU平台上的性能更好。下面的代码对包含1亿个整数的数组分别使用parallelSort和sort进行排序。

Random random = new Random();
int count = 100000000;
int[] array = new int[count];
Arrays.parallelSetAll(array, (index) -> random.nextInt());
int[] copy = new int[count];
System.arraycopy(array, 0, copy, 0, array.length);
Arrays.parallelSort(array);
Arrays.sort(copy);

在本人的4核CPU的平台上,parallelSort和sort方法的耗时分别是7112毫秒和16777毫秒。所以parallelSort方法的性能要好不少。不过parallelSort方法只在数据量较大时有比较明显的性能提升。当数据量较小时,Fork/Join框架本身所带来的额外开销足以抵消它带来的性能提升。

集合批量数据操作

在Java应用的开发中,对集合的操作是比较常见的。不过在Java SE 8之前的Java标准库中,对集合所能进行的操作比较有限,基本上都围绕集合遍历来展开。相对于其他编程语言来说,Java标准库在这一块是比较弱的。Java SE 8中lambda表达式的引入以及标准库的增强改进了这种状况。具体来说体现在两个方面上的改进:第一个方面是对集合的操作方式上。得益于默认方法的引入,Java集合框架中的接口可以进行更新,添加了更多有用的操作方式,即通常所说的“filter/map/reduce”等操作。第二个方面是对集合的操作逻辑的表示方式上。新添加的操作方式使用了java.util.function包中的新的函数式接口,可以很方便地使用lambda表达式来表示对集合的处理逻辑。这两个方面结合起来,得到的是更加直观和简洁的代码。

新的集合批量处理操作的核心是新增的java.util.stream包,其中最重要的是java.util.stream.Stream接口。Stream接口的概念类似于Java I/O库中的流,表示的是一个支持顺序和并行操作的元素的序列。在该序列上可以进行不同的转换操作。序列中包含的元素也可以被消费以产生所需的结果。Stream接口所表示的只是操作层面上的抽象,与底层的数据存储并没有关系。通常的使用方式是从集合中创建出Stream接口的对象,再进行各种不同的转换操作,最后消费操作执行的结果。

Stream接口中包含的操作分成两类:第一类是对序列中元素进行转换的中间操作,如filter和map等。这类中间操作是延迟进行的,可以级联起来。第二类是消费序列中元素的终止操作,如forEach和count等。当对一个Stream接口的对象执行了终止操作之后,该对象无法被再次处理。这点符合一般意义上对于“流”的理解。下面的代码给出了Stream接口中的filter、map和reduce操作的基本使用方式。Stream接口中的方法大量使用了函数式接口,可以用lambda表达式很方便地进行操作。

IntStream.range(1,10).filter(i -> i % 2 == 0).findFirst().ifPresent(System.out::println);
//保留偶数并输出第一个元素

IntStream.range(1,10).map(i -> i * 2).forEach(System.out::println); //所有元素乘以2并输出

int value = IntStream.range(1, 10).reduce(0, Integer::sum); //求和

Stream接口的reduce操作还支持一种更加复杂的用法,如下面的代码所示:

List<String> fruits = Arrays.asList(new String[] {"apple", "orange", "pear"});
int totalLength = fruits.stream().reduce(0, (sum, str) -> sum + str.length(), Integer::sum);
//字符串长度的总和

这种方式的reduce方法需要3个参数,分别是初始值、累积函数和组合函数。初始值是reduce操作的起始值;累积函数把部分结果和新的元素累积成新的部分结果组合函数则把两个部分结果组合成新的部分结果,最后产生最终结果。这种形式的reduce操作通常可以简化成一个map操作和另外一个简单的reduce操作,如下面的代码所示。两种方式的效果是一样的,不过下面的方式更加容易理解一些。

int totalLength = fruits.stream().mapToInt(String::length).reduce(0, Integer::sum);

另外一种特殊的reduce操作是collect操作。它与reduce的不同之处在于,collect操作的过程中所进行的是对一个结果对象进行修改操作。这样可以避免不必要的对象创建,提高性能。下面代码中的结果是一个StringBuilder类的对象。

StringBuilder upperCase = fruits.stream().collect(StringBuilder::new, (builder, str)
-> builder.append(str.substring(0, 1).toUpperCase()), StringBuilder::append);
//字符串首字母大写并连接

Stream接口中的操作可以是顺序执行或并行执行的。这是在Stream接口的对象创建时所确定的。比如Collection接口提供了stream和parallelStream方法来创建两种不同执行方式的Stream接口的对象。这两种不同的方式是可以切换的,通过Stream接口的sequential和parallel方法就可以完成。

日期和时间

Java标准库中的日期和时间处理API一直为开发人员所诟病。大多数开发人员会选择Joda Time这样的第三方库来进行替代。JSR 310作为Java SE 8的一部分,重新定义了新的日期和时间API,借鉴了已有第三方库中的最佳实践。I定义在java.time包中的新的日期和时间API基于标准的ISO 8601日历系统。

在新的日期和时间API中,核心的类是LocalDateTime、OffsetDateTime和ZonedDateTime。LocalDateTime类表示的是ISO 8601日历系统中不带时区的日期和时间信息。OffsetDateTime类在基本的日期和时间基础上增加了与UTC的偏移量。ZonedDateTime类则加上了时区的相关信息。下面的代码给出了日期和时间API的基本用法,包括对日期和时间的修改、输出和解析。

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/Java/

LocalDateTime.now().plusDays(3).minusHours(1).format(DateTimeFormatter
.ISO_LOCAL_DATE_TIME); //输出日期和时间
ZonedDateTime.now().withZoneSameInstant(ZoneId.of("GMT+08:00")).format
(DateTimeFormatter.ISO_ZONED_DATE_TIME); //输出日期、时间和时区
DateTimeFormatter.ofPattern("yyyy MM dd").parse("200101 25").
query(TemporalQuery.localDate()); //日期的解析

除了上述3个类之外,还有几个值得一提的辅助类。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 并行函数库
, 接口
, java se
, 方法
, stream
, 日期
, java8 java.time引用
, reduce
, joda
, java日期处理类
, Map/Reduce框架
, Java日期函数
reduce方法
javase、java、java se 6、java se 6 mac下载、jdk,以便于您获取更多的相关知识。

时间: 2024-08-03 15:49:29

Java SE 8:标准库增强的相关文章

java se ee me语法相同,只是方法不同吗?还是连语法也不相同?

问题描述 java se ee me语法相同,只是方法不同吗?还是连语法也不相同? 1.java se ee me语法相同,只是方法不同吗?还是连语法也不相同? 2.java se是标准平台吗? 安卓SDK是方法? 3.可不可以不学SE,直接学java ee呢?主要想做网站,不想开发安卓程序? 解决方案 java是语言,se ee me是平台.语言只有一套,不存在什么语法差异.类库有三套,其中me是精简的,ee是企业的,前者规模要小. 学网站要学ee,se包含的基本类库ee中也用得着. 解决方案

Java SE 6 新特性: HTTP 增强

2006 年底,Sun 公司发布了 Java Standard Edition 6(Java SE 6)的最终正式版,代号 Mustang(野马).跟 Tiger(Java SE 5)相比,Mustang 在性能方面有了不错的提升.与 Tiger 在 API 库方面的大幅度加强相比,虽然 Mustang 在 API 库方面的新特性显得不太多,但是也提供了许多实用和方便的功能:在脚本,WebService,XML,编译器 API,数据库,JMX,网络和 Instrumentation 方面都有不错

《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一第1章 Java SE 8的流库

第1章 Java SE 8的流库 流提供了一种让我们可以在比集合更高的概念级别上指定计算的数据视图.通过使用流,我们可以说明想要完成什么任务,而不是说明如何去实现它.我们将操作的调度留给具体实现去解决.例如,假设我们想要计算某个属性的平均值,那么我们就可以指定数据源和该属性,然后,流库就可以对计算进行优化,例如,使用多线程来计算总和与个数,并将结果合并. 在本章中,你将会学习如何使用Java的流库,它是在Java SE 8中引入的,用来以"做什么而非怎么做"的方式处理集合.

《Java安全编码标准》一3.2 DCL01-J不要重用Java标准库的已经公开的标识

3.2 DCL01-J不要重用Java标准库的已经公开的标识 不要重用那些在Java标准库中已经使用过的公共的标识.公共的工具类.接口或者包.当一个程序员使用和公开类相同的名字时,如Vector对后来的维护者来说,他可能不知道这个标识并不是指?java.util.Vector?,并且可能会无意地使用这个自定义的Vector类而不是原有的java.util.Vector类.使得这个自定义的?Vector会遮蔽java.util.Vector类,正如在JLS的6.3.2节中提到的那样.从而会导致不可

Java SE 6中的AWT模态增强功能

一. 引言 模态一直是我最喜欢的话题之一,至少因为一直存在大量的感兴趣的客户的有关于这方面内容的回馈信息.作为一个Java SE测试工程师,这正是驱动我工作的动力-它使我一直处于忙碌之中,而且还为我的工作带来快乐.另一方面,这也说明了模态是客户端最广为使用的特征之一,不管是使用Swing还是使用AWT进行开发. 在Java SE 6(代码名为Mustang)中,我的工作变得更有意思--在模态方面进行大量的改进.这些改进将为应用程序开发者提供更大的灵活性--在设计可能用到模态对话框行为的程序的过程

用Java SE 6.0实现高质量桌面集成开发

提要:本文将以具体的实例向你展示Java SE 6在桌面开发中所提供的一系列优秀特征. 一. 引言 随着Java SE 6 Beta的发行,Java开发者再也不需要自己去实现Java本机接口(JNI)便可以在其应用程序中加入桌面产品所具有的特征.这些桌面集成特征现在已成为内核的一个组成部分. 最新的Java标准版本6.0(代码名为Mustang)将在功能上进行一系列的改进--开发者们能够方便地用Java处理安全,JMX,操作系统文件,国际化和桌面开发等一系列问题.Sun在开发这个版本的过程中表现

Java SE 6在Solaris的可观察性特征分析

Java平台标准版(Java SE)6,代码名为"Mustang",是最新的Java SE发行版本(正在开发中).Java SE 6源码和二进制代码都可以在www.Java.net上下载.Java SE 6平台要到2006年秋天才能正式发布.不过,现在你可以下载试用Java SE 6 Beta版. Java SE 6平台中提供了多种可观察性(observability)工具,这其中的许多工具都可在系统中运行,而这些工具中的只有极少数被用于挂起进程或核心复制处理.因此,在本文中,我们将分

Java SE 8: Lambda表达式

Java SE 8在6月13的版本中已经完全了全部的功能.在这些新的功能中,lambda表达式是推动该版本发布 的最重要新特性.因为Java第一次尝试引入函数式编程的相关内容.社区对于lambda表达式也期待已久. Lambda表达式的相关内容在JSR 335中定义,本文的内容基于最新的规范和JDK 8 Build b94. 开发环境使用 的是Eclipse. Lambda表达式 要理解lambda表达式,首先要了解的是函数式接口(functional interface).简单来说,函数式接口

第十章 Python常用标准库/模块使用(必会)

本章涉及标准库: 1.sys 2.os 3.glob 4.math 5.random 6.platform 7.pikle与cPikle 8.subprocess 9.Queue 10.StringIO 11.logging 12.ConfigParser 13.urllib与urllib2 14.json 15.time 16.datetime 10.1 sys 1)sys.argv 命令行参数. argv[0] #代表本身名字 argv[1] #第一个参数 argv[2] #第二个参数 ar