java8list⾏转列_Java14都来了,你还不会⽤Java8吗?
Java 8 于2014年3⽉18⽇发布,并且成为主流的 Java,如今,虽然 Java 14 都已经发布了,但是 开发者和公司选择的版本依旧是经久
不衰的 Java 8 版本,如果你还不了解这些新特性,是时候学习⼀下了。
Java 8 更新的⼀些重要功能⼀览
Iterable 接⼝中的 forEach() ⽅法
接⼝中的默认⽅法和静态⽅法
功能接⼝和 Lambda 表达式
⽤于集合上批量数据操作的 Java Stream API
Java 时间 API
集合 API 的改进
并发 API 改进
Java IO改进
其他核⼼ API 改进
下⾯来简要了解⼀下这些Java 8功能。我将提供⼀些代码⽚段以更好地理解,因此,如果要在Java 8中运⾏程序,则必须按照以下步骤设
置Java 8环境。
下载并安装JDK8。像其他Java版本⼀样,安装也很简单,运⾏下⾯的⽰例,必须要安装 JDK 环境。
下载最新的 IDEA 开发环境,这⾥我不推荐使⽤ Eclipse ,但是如果你有使⽤ Eclipse 习惯,那我在这⾥推荐你可以尝试 IDEA,因为它真
的太棒啦~
Iterable 接⼝中的 forEach()⽅法
在 Java 8 以前,每当需要遍历 Collection 时,就需要创建⼀个 Iterator 来进⾏迭代 Collection 对象,然后针对 Collection 中 的每个元
素将业务逻辑循环在⼀起。如果迭代器使⽤不正确,可能会抛出 ConcurrentModificationException。
Java 8 在接⼝中引⼊了forEach⽅法,java.lang.Iterable因此在编写代码时,我们仅关注业务逻辑。forEach⽅法将
java.util.function.Consumer对象作为参数,因此有助于将我们的业务逻辑放在⼀个可以重⽤的单独位置。让我们通过简单的⽰例查看forEach⽤法。
package com.journaldev.java8.foreach;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.function.Consumer;import java.la
代码的⾏数可能会增加,但是forEach⽅法有助于将迭代逻辑和业务逻辑放在不同的位置,从⽽使关注点和代码更清晰地分离。
接⼝中的默认⽅法和静态⽅法
如果仔细阅读forEach⽅法的详细信息,会注意到它是在Iterable接⼝中定义的,但我们知道接⼝不能具有⽅法主体。从Java 8开始,接⼝
已增强为具有实现的⽅法。我们可以使⽤default和static关键字来创建带有⽅法实现的接⼝。Iterable接⼝中的forEach⽅法实现为:
default void forEach(Consumer super T> action) { quireNonNull(action); for (T t : this) { action.accept(t); }}
我们知道Java不会在Class中提供多重继承,因为它会导致Diamond问题。由于接⼝现在类似于抽象类,因此现在如何使⽤接⼝处理它。解决⽅案是在这种情况下编译器将引发异常,我们将不得不在实现接⼝的类中提供实现逻辑。
package com.journaldev.java8.defaultmethod;@FunctionalInterfacepublic interface Interface1 { void method1(String str); default void log(String str){ package com.journaldev.java8.defaultmethod;@FunctionalInterfacepublic interface Interface2 { void method2(); default void log(String str){ System 注意,两个接⼝都有⼀个带有实现逻辑的通⽤⽅法log()。
package com.journaldev.java8.defaultmethod;public class MyClass implements Interface1, Interface2 { @Override public void method2() { } @Ove
如你所见, Interface1 具有在 MyClass.log() ⽅法实现中使⽤的静态⽅法实现。Java 8 在 Collection API 中⼤量使⽤默认和静态⽅法,
并且添加了默认⽅法,以便使 JDK 8 之前的代码保持向后兼容。
如果层次结构中的任何类都具有具有相同的⽅法,则默认⽅法将变得⽆关紧要。由于任何实现接⼝的类都已经具有 Object 作为超类,因此
如果接⼝中具有 equals(),hashCode() 默认⽅法,它将变得⽆关紧要。这就是为什么为了更清楚起见,不允许接⼝具有Object默认⽅
法。
java安装完整教程有关Java 8接⼝特性的完整详细信息,请阅读 Java 8接⼝更改。
功能接⼝和Lambda表达式
如果你注意到上述接⼝代码,则会注意到 @FunctionalInterface 注解。该功能接⼝是Java 8 中引⼊的新概念。具有⼀种抽象⽅法的接⼝
就变成了功能接⼝。我们不需要使⽤ @FunctionalInterface 注解将接⼝标记为Functional Interface。@FunctionalInterface 注解是⼀
种避免在功能接⼝中意外添加抽象⽅法的⼯具。您可以将其视为 @Override 批注,并且是使⽤它的最佳实践。java.lang.Runnable 使⽤单个抽象⽅法 run() 是功能接⼝的⼀个很好的例⼦。
功能接⼝的主要优点之⼀是可以使⽤ lambda 表达式实例化它们。在 Java 8 之前,可以⽤匿名类实例化⼀个接⼝,但是代码看起来很庞
⼤。
Runnable r = new Runnable(){ @Override public void run() { System.out.println("My Runnable"); }};
由于功能接⼝只有⼀种⽅法,因此 lambda 表达式可以轻松提供该⽅法的实现。只需要提供⽅法参数和业务逻辑。例如,可以使⽤ lambda
表达式编写上⾯的实现:
Runnable r1 = () -> { System.out.println("My Runnable"); };
如果⽅法实现中只有⼀条语句,那么我们也不需要花括号。例如,上⾯的Interface1匿名类可以使⽤lambda实例化,如下所⽰:
Interface1 i1 = (s) -> System.out.println(s);i1.method1("abc");
因此,lambda 表达式是轻松创建功能接⼝的匿名类的⼀种⽅法。使⽤ lambda 表达式对于代码运⾏没有任何的影响,因此要谨慎谨慎使⽤它,因为我们并不介意编写⼀些额外的代码⾏。
新包装 java.util.function 添加了带有功能接⼝束的,以提供 lambda 表达式和⽅法引⽤的⽬标类型。Lambda 表达式是⼀个⾮常复杂的话题,后续我会编写⼀篇⽂章专门针对 lambda 表达式。
您可以在 Java 8 Lambda Expressions Tutorial 中阅读完整的教程。
⽤于集合上批量数据操作的Java Stream API
java.util.stream 是Java 8中添加的⼀个新内容,以对该集合执⾏类似过滤/映射/遍历的操作。Stream API 将允许顺序执⾏和并⾏执⾏。这对我来说是⾮常好⽤的⼀个功能,因为我经常处理 Collections,⽽且通常使⽤很多的数据进⾏过滤数据,遍历数据,stream 就完美的
解决了这个问题。
Collection 接⼝已使⽤ stream() 和 parallelStream() 默认⽅法进⾏了扩展,以获取⽤于顺序执⾏和并⾏执⾏的 Stream ,⽤⼀个简单的
例⼦看看它们的⽤法。
package com.journaldev.java8.stream;import java.util.ArrayList;import java.util.List;import java.util.stream.Stream;public class StreamExample { public st 如果你运⾏⽰例代码,将获得如下输出:
High Nums parallel=91High Nums parallel=96High Nums parallel=93High Nums parallel=98High Nums parallel=94High Nums parallel=95High Nums parall 请注意,并⾏处理的时候。值不按顺序排列,因此在处理庞⼤的集合时,并⾏处理将⾮常有帮助。
这篇⽂章⽆法涵盖有关Stream API的所有内容,您可以在 Java 8 Stream API Example Tutorial 中阅读有关Stream API的所有内容。Java 8 时间API
在之前的 Java 中使⽤⽇期,时间和时区⼀直很困难。Java 中没有⽤于⽇期和时间的标准⽅法或 API。Java 8 有⼀个不错的附加功能是java.time 软件包,它简化了 Java 中使⽤时间的过程。
仅查看 Java Time API 软件包,就可以感觉到它⾮常易于使⽤。它具有⼀些⼦包 java.time.format,这些⼦包提供⽤于打印和解析⽇期和时间的类,还有 提供对时区及其规则的⽀持。
新的 Time API 在整⽉的⼏个⽉和⼀周中的⼏天中都使⽤了枚举⽽不是整数常量。常⽤的类之⼀是 DateTimeFormatter 将 DateTime 对
象转换为字符串。
有关完整的教程,请转到 Java⽇期时间API⽰例教程。
集合API的改进
在上⾯的介绍已经看到了 forEach() ⽅法和⽤于集合的 Stream API。
Collection API 中添加的⼀些新⽅法是:
IteratorforEachRemaining(Consumer action) 在所有元素都已处理完毕或该动作引发异常之前,对其余每个元素执⾏给定操作的默认⽅法。
CollectionremoveIf(Predicate filter) 删除此集合中所有满⾜给定谓词的元素的默认⽅法。
Collection spliterator() 该⽅法返回Spliterator实例,该实例可⽤于顺序或并⾏遍历元素。地图replaceAll(),compute(),merge()⽅法。
另外还有⼀些具有 hash 冲突 的HashMap 类的性能改进
并发API改进
⼀些重要的并发API增强功能包括:
ConcurrentHashMap compute(),forEach(),forEachEntry(),forEachKey(),forEachValue(),merge(),reduce()和search()
⽅法。CompletableFuture 可以明确完成(设置其值和状态)。Executors newWorkStealingPool() 使⽤所有可⽤处理器作为⽬标并⾏度
级别创建窃取线程池的⽅法。
Java IO改进
我知道的⼀些IO改进:
Files.list(Path dir) 返回⼀个延迟加载的 Stream,其元素是⽬录中的⽂件夹和⽂件列表。
Files.lines(Path path) 返回⼀个读取指定⽂件所有⾏的⽂件流。
Files.find() 返回⼀个根据指定⽬录搜索指定⽂件的⽂件列表流。
BufferedReader.lines() 返回⼀个Stream,其元素是从此 BufferedReader 中读取的⾏。
其他核⼼API改进
⼀些杂项API改进在某些特殊情况可能会派上⽤场:
ThreadLocal 静态⽅法可以使⽤ withInitial ⽅法创建实例。
⽐较器接⼝已扩展了许多默认和静态⽅法,⽤于⾃然排序,反向排序等。
Integer,Long 和 Double 包装器类中增加了 min(),max() 和 sum() ⽅法。
Boolean 类中的 logicalAnd() ,logicalOr() 和 logicalXor() ⽅法。
ZipFile.stream() ⽅法获取 ZIP ⽂件条⽬上的有序Stream,并以压缩时的顺序出现在 Stream 中。
Math 类中增加了⼏种实⽤⽅法。
jjs 添加命令以调⽤ Nashorn Engine。
jdeps 添加命令以分析类⽂件
JDBC-ODBC 桥已被删除。
PermGen 内存空间已被删除
码字不易,如果能帮到你,请点点关注~
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论