GTLC全球技术领导力峰会·上海站,首批讲师正式上线! 了解详情
写点什么

Java 8 全面解析

2013 年 8 月 31 日

TechEmpower 是位于加利福尼亚州埃尔塞贡多的一家定制应用开发公司,该公司发表了一篇题为“ Java 8 全面解析”的博客文章。该博客文章全面概括了开发者在即将到来的 Java 8 中所要面对的变化。下面的内容快速概括了该博客文章中的信息。如果想查看所有的细节请访问 TechEmpower 的博客文章。

改进接口

现在可以在接口中定义静态方法了。例如,java.util.Comparator 接口中现在拥有一个静态的 naturalOrder 方法。

复制代码
public static <T extends Comparable<? super T>> Comparator <T>naturalOrder() {
return (Comparator<T>) Cmparators.NaturalOrderComparator.INSTANCE;
}

还能够在接口中提供默认方法。通过该功能,程序员能够在不破坏已有的接口实现代码的前提下添加新方法。例如,java.lang.Iterable 接口现在拥有一个默认的 forEach 方法。

复制代码
public default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}

注意,接口不能为 Object 类中的任何方法提供默认的实现。

函数式接口

函数式接口是只定义了一个抽象方法的接口。Java 8 引入了 FunctionalInterface 注解来表明一个接口打算成为一个函数式接口。例如,java.lang.Runnable 就是一个函数式接口。

复制代码
@FunctionalInterface
public interface Runnable {
public abstract void run();
}

注意,不管 FunctionalInterface 注解是否存在,Java 编译器都会将所有满足该定义的接口看作是函数式接口。

Lambda

函数式接口的重要属性是:我们能够使用 lambda 实例化它们,Lambda 表达式让你能够将函数作为方法参数,或者将代码作为数据对待。下面是 Lambda 的一些例子。输入在左边,代码在右边。输入类型能够被推断出来,同时是可选的。

复制代码
(int x, int y) ->{ return x + y; }
(x, y) -> x + y
x -> x * x
() -> x
x -> { System.out.println(x); }

下面是实例化 Runnable 函数式接口的一个例子。

复制代码
Runnable r = () ->{ System.out.println("Running!"); }

方法引用

方法引用是简洁的 Lambda 表达式,能够用于已经拥有名称的方法。下面是一些方法引用的例子,右边是同样效果的 Lambda 表达式。

复制代码
String::valueOf x ->String.valueOf(x)
Object::toString x ->x.toString()
x::toString () ->x.toString()
ArrayList::new () -> new ArrayList<>()

与捕获相对的非捕获 Lambda

如果使用 Lambda 表达式访问一个在 Lambda 语句体外定义的非静态变量或者对象,那么它会被说成是“捕获”。例如,下面的 Lambda 会访问变量 x:

复制代码
int x = 5;
return y -> x + y;

一个 Lambda 表达式仅能够访问 final 或者有效 final 封闭块中的局部变量和参数。

java.util.function

新版本向 java.util.function 包中添加了很多新的函数式接口。下面是一些例子:

  • Function<T, R>——将 T 作为输入,返回 R 作为输出
  • Predicate——将 T 作为输入,返回一个布尔值作为输出
  • Consumer——将 T 作为输入,不返回任何内容
  • Supplier——没有输入,返回 T
  • BinaryOperator——将两个 T 作为输入,返回一个 T 作为输出

java.util.stream

新的 java.util.stream 包提供了对值流进行函数式操作的类。从一个集合中获取流的一种常见方式是:

复制代码
Stream<T> stream = collection.stream();

下面是一个来自于 Javadocs 包中的例子。

复制代码
intsumOfWeights = blocks.stream().filter(b ->b.getColor() == RED)
.mapToInt(b ->b.getWeight())
.sum();

在该例子中我们首先使用了一个块集合作为流的来源,然后在流上执行了 filter-map-reduce 操作获取红块重量的和。

流可以是无限的、有状态的,可以是顺序的,也可以是并行的。在使用流的时候,你首先需要从一些来源中获取一个流,执行一个或者多个中间操作,然后执行一个最终操作。中间操作包括 filter、map、flatMap、peel、distinct、sorted、limit 和 substream。终止操作包括 forEach、toArray、reduce、collect、min、max、count、anyMatch、allMatch、noneMatch、findFirst 和 findAny。 java.util.stream.Collectors 是一个非常有用的实用类。该类实现了很多归约操作,例如将流转换成集合和聚合元素。

改进了泛型推断

这提升了 Java 编译器推断泛型和在泛型方法调用中减少显式类型参数的能力。在 Java 7 中,代码如下:

复制代码
foo(Utility.<Type>bar());
Utility.<Type>foo().bar();

在 Java 8 中,改进后的参数和调用链推断让你能够按照下面的方式编写代码:

复制代码
foo(Utility.bar());
Utility.foo().bar();

java.time

新的日期 / 时间 API 包含在 java.time 包中。所有的类都是不可变且线程安全的。日期和时间类型包括 Instant、LocalDate、LocalTime、LocalDateTime 和 ZonedDateTime。除了日期和时间之外,还有 Duration 和 Period 类型。另外,值类型包括 Month、DayOfWeek、Year、 Month、YearMonth、MonthDay、OffsetTime 和 OffsetDateTime。这些新的日期 / 时间类大部分 JDBC 都支持。

新增集合 API

接口可以拥有默认函数的能力让 Java 8 得以向集合 API 中添加大量的新方法。所有的接口都提供了默认的实现,而更加有效的实现则是被添加到了具体的类中。下面是新方法的列表:

  • Iterable.forEach(Consumer)
  • Iterator.forEachRemaining(Consumer)
  • Collection.removeIf(Predicate)
  • Collection.spliterator()
  • Collection.stream()
  • Collection.parallelStream()
  • List.sort(Comparator)
  • List.replaceAll(UnaryOperator)
  • Map.forEach(BiConsumer)
  • Map.replaceAll(BiFunction)
  • Map.putIfAbsent(K, V)
  • Map.remove(Object, Object)
  • Map.replace(K, V, V)
  • Map.replace(K, V)
  • Map.computeIfAbsent(K, Function)
  • Map.computeIfPresent(K, BiFunction)
  • Map.compute(K, BiFunction)
  • Map.merge(K, V, BiFunction)
  • Map.getOrDefault(Object, V)

新增并发 API

Java 8 还向并发 API 中添加了一些新内容,我们将会在此简要介绍其中的一部分。ForkJoinPool.commonPool() 是处理所有并行流操作的结构。没有明确提交到某个特定池中的所有 ForkJoinTask 都将会使用通用池。ConcurrentHashMap 已经被完全重写。StampedLock 是一个新的锁实现,它可以作为 ReentrantReadWriteLock 的一个备选方案。CompletableFuture 是 Future 接口的一个实现,它为异步任务的执行和链接提供了方法。

新增 IO/NIO API

在 Java 8 中有一些新的 IO/NIO 方法,我们能够使用它们从文件或者输入流中获取 java.util.stream.Stream。

  • BufferedReader.lines()
  • Files.list(Path)
  • Files.walk(Path, int, FileVisitOption…)
  • Files.walk(Path, FileVisitOption…)
  • Files.find(Path, int, BiPredicate, FileVisitOption…)
  • Files.lines(Path, Charset)
  • DirectoryStream.stream()

这里面有一个新的 UncheckedIOException,它是一个继承了 RuntimetimeException 的 IOException。还有一个 CloseableStream,它是一个能够并且应该被关闭的流。

反射和注解的变化

通过类型注解,我们能够在更多的地方使用注解,例如像List<@Nullable String> 这样的泛型参数中。这增强了通过静态分析工具发现错误的能力,它将增强并重定义Java 内置的类型系统。

Nashorn JavaScript 引擎

Nashorn 是一个集成到 JDK 中的新的、轻量级、高性能的 JavaScript 实现。Nashorn 是 Rhino 的继任者,它提升了性能和内存使用情况。它将会支持 javax.script API,但是它并不会支持 DOM/CSS,也不会包含浏览器插件 API。

java.lang、java.util 等其他地方的新增功能

Java 8 还向很多其他的包中添加了大量其他的功能,在本文中我们并没有提及。下面是一些值得注意的内容。可以使用 ThreadLocal.withInitial(Supplier) 更加简洁的声明本地线程变量。长期未兑现的 StringJoiner 和 String.join(…) 现在已经是 Java 8 的一部分了。比较器提供了一些新的方法能够用于链接和基于域的比较。默认的字符串池映射大小更大了,大约在 25—50K。

如果想要获取更加详细的介绍可以访问博客文章 Java 8 全面解析。该博客文章的最后一次更新时间是 2013 年 5 月 29 日。

查看英文原文 Everything About Java 8

2013 年 8 月 31 日 02:319231
用户头像

发布了 321 篇内容, 共 103.6 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
  • Eclipse Collections:让 Java Streams 更上一层楼

    Eclipse Collections是Java的高性能集合框架,为原生JDK集合增加了丰富的功能。在本文中,关键框架贡献者演示了如何将标准Java代码重构为Eclipse Collections数据结构和API,并减小内存开销。

  • Eclipse Collections 随 Java 版本的演变

    对于Java的每个后继版本,框架都必须调整转化,以便保持同步。本文将介绍高性能Java集合框架Eclipse Collections中部分Java 8的新特性,并展望下我们针对Java 9所做的一些新东西。本文将大致介绍下这些新特性及变化。

  • sun.misc.Unsafe 的后启示录

    Java 9将要移除sun.misc.Unsafe和其他私有的API,在Java社区中引起了分歧,这在Java 20年的历史中是没有发生过的。尽管已经有了解决方案的提议,并且也提供了迁移路径,但是依然有一个很大的问题:后sun.misc.Unsafe的世界会是什么样子呢?

  • C# 8 中的默认接口方法

    默认接口方法已经被包含在C# 8的新功能建议中,开发人员可以像使用trait那样使用默认方法。trait是面向对象的编程技术,用于提升不相关类之间方法的重用性。C#语言开发人员基于Java的默认方法概念开发此功能。

  • Oracle 确定 Unsafe 类处理策略

    在上周的一篇博文中,Oracle明确了sun.misc.Unsafe类的一些方向(来自不受支持的sun.misc包)。关于这个讨论中的问题,现在需要关注的是,这个应用广泛的类将来仅限于通过Jigsaw项目的JDK模块来访问。

  • 装饰器模式:通过剖析 Java IO 类库源码学习装饰器模式

    装饰器模式主要解决继承关系过于复杂的问题,通过组合来替代继承。它主要的作用是给原始类添加增强功能。

    2020 年 2 月 26 日

  • 自 Java 8 以来的新语言特性

    本文介绍了自 Java 8 以来与 Java 语言相关的改进。密切关注 Java 平台是很重要的,因为按照新的快速发布节奏,每六个月就会发布一个新的 Java 版本对平台和语言进行更改。

  • Java 10 发布

    Oracle发布了新版本的Java,即Java 10。这个版本距离Java 9的发布刚刚过去了六个月,这是另外一个特性发布版本,其生命周期只有六个月。下一个长期支持的发布版本是Java 11,预计会在九月份发布。

  • Java 8 vs. Scala 之 Lambda 表达式

    2014年3月份众人期待已久的Java 8发布了,新版本从语言、编译器、类库和工具等方面对Java进行了诸多改进与提升,一时间风光无限;而JVM体系的另一门语言Scala则因为融合了函数式编程语言与面向对象编程语言的优点,从诞生以来就一直备受瞩目,迅速赢得了社区的强烈支持。两门语言孰优孰劣或许不能简单地做出定论,这取决于具体的应用场景、资源约束以及团队偏好等因素,但是无论作何选择首先都需要对它们有深入的了解,本文来自于Zappos公司Hussachai Puripunpinyo在Dzone上发表的一篇文章,介绍了他自己对Java和Scala Lambda表达式的看法。

  • GS Collections 实例教程(第二部分)

    Donald Raab,高盛在2012年开源的GS Collections的创作者,本文以实例展示这一框架的优势,以及如何与Lambda 表达式一起,在Java中应用Smalltalk的特点。

  • Quaere:Java 上的 LINQ

    在上周的JavaZone大会上,Anders Noras介绍了Quaere函数库,他这个库比喻成Java上的LINQ。Quaere是一门DSL,任何实现了Iterable或其Queryable接口的结构,Quaere都能提供查询功能。

  • JVM 是如何实现反射的?

    反射是Java语言中一个相当重要的特性,它允许正在运行的Java程序观测,甚至是修改程序的动态行为。

    2018 年 8 月 6 日

  • 5 道常见的 Java 面试题

    前Oracle首席工程师为你讲解Java常见面试题,带你巩固Java核心知识点。

  • .NET 4.5 对 Base Class Library 做出改善

    Base Class Library是.NET开发平台的核心。 不管你使用了何种配置或者前端技术,都会在应用程序中找到使用BCL的地方。 这次,我们看到了在流、集合和改善的弱引用方面的提升。

  • 打通前端与原生的桥梁:JavaScriptCore 能干哪些事情?

    总结来说,JavaScriptCore 提供了前端与原生相互调用的接口。

    2019 年 6 月 11 日

  • Scala 2.11.0 发布

    在经过4个RC版本之后,Scala 2.11.0正式发布,该版本主要针对Java 6,并开始试验性的支持Java 8,比如读取Java 8字节码、解析Java 8源代码。另外,在2.10.x系列版本上构建的,没有过时警告Scala的代码可以在2.11平台正常构建。Scala 2.11.0修复了2.10.x中的613个BUG,并在2.10系列的基础上做了大幅改进,官方宣称Scala 2.11的设计目标是更小、更快和更稳健。

  • JVM 是如何处理异常的?

    异常处理的两大组成要素是抛出异常和捕获异常。这两大要素共同实现程序控制流的非正常转移。

    2018 年 8 月 1 日

  • 小议 Java 语言

    很多新人入门会要求我推荐编程语言,Java 属于我推荐的语言之一,因为 Java 标准、规范,是面向对象编程的代表,在学习其他编程语言的时候还可以参考互通。

    2018 年 1 月 12 日

  • Android JVM TI 机制详解(内含福利彩蛋)

    JVM TI机制究竟是什么?它为什么如此的强大?怎么样将它应用到我们的工作中?今天我们一起来解开它神秘的面纱。

    2018 年 12 月 25 日

发现更多内容

金沙江创投主管合伙人朱啸虎:RPA+AI构建企业智能生产力,驱动商业智能变革

人称T客

【week07】作业

chengjing

第7周作业一

ruettiger

架构师第七周学习总结

小蚂蚁

一周信创舆情观察(7.13~7.19)

统小信uos

数据库 舆情 芯片

【week07】总结

chengjing

【研报下载】InfoQ《2020中国技术发展白皮书》重磅发布

InfoQ写作平台官方

写作平台 InfoQ 白皮书 研究报告 活动专区

JAVA已过气?中俄大佬对话告诉你俄罗斯最受欢迎的编程语言是什么!

华为云开发者社区

Java 开源 程序员 Lambda 编程语言

MySQL常用函数

Bruce Duan

mysql常用函数

阿里官方 Redis 开发规范

Bruce Duan

redis Redis开发规范

架构师训练第七周

邵帅

计算机网络基础(九)---网络层-内部网关路由协议

书旅

计算机网络 网络协议 操作系统 计算机基础

架构师训练营第七周作业

Bruce Xiong

Kubernetes 1.0 发布刚六周年,IBM 却想招 12 年经验的

神经星星

程序员 Kubernetes 云原生 招聘 ibm

工作总结

Arthur

你只加了两行代码,为什么要花两天时间?

Yukun

程序员 debug bug

通过双 key 来解决缓存并发问题

Bruce Duan

缓存穿透 缓存并发 双key解决缓存并发

架构师训练营作业-web性能压测示例代码

superman

极客大学架构师训练营

架构师培训第七周练习

小蚂蚁

明势资本创始合伙人黄明明:人机协作,重塑未来工作方式

人称T客

专治数仓疑难杂症!美团点评 Flink 实时数仓应用经验分享

Apache Flink

flink

架构师训练第七周总结

邵帅

作业1

东哥

极客大学架构师训练营

第7周总结

叶鹏

【DevCloud·敏捷智库】如何利用故事点做估算

华为云开发者社区

敏捷 敏捷开发 需求 故事 华为云

总结

ruettiger

埋点全解析,你最关心的可视化埋点在这里!

易观大数据

后疫情生产力时代智能自动化打造以人为中心的企业

人称T客

秒懂云通信:如何用阿里云平台发短信?

阿里云Edge Plus

性能测试

考尔菲德

报销流程太慢太复杂?区块链技术引入票据系统效率翻一倍

CECBC区块链专委会

数据共享 电子票据 优化业务 可信体系

DNSPod与开源应用专场

DNSPod与开源应用专场

Java 8全面解析-InfoQ