在Java 8中,功能编程和lambda被添加为语言功能。函数式编程的两个核心范例是不变的值和将函数提升为一等公民的方法。数据经过一系列修改步骤,其中每个步骤都需要一些输入并将其映射到新的输出。函数式编程可与Java中的Streams和null安全monad(可选)一起使用,如下所示…
List<String> stringList = Arrays.asList("Hello", "World", "How", "Are", "You", "Today");
//functional style
stringList.stream()
.filter(s -> s.equals("Hello") || s.equals("Are"))
.map(s -> s + " String")
.forEach(System.out::println);
流(Java 8)
对于一般的计算机程序,通常必须使用值列表,并对每个值执行给定的转换。在Java 8之前,您必须使用for循环进行此转换,但是从现在开始,您可以按以下方式使用Streams:
Stream.of("hello", "great")
.map(s -> s + " world")
.forEach(System.out::println);
> hello world
> great world
map函数将一个lambda作为输入,它将应用于流中的所有元素。
流可以在列表,集合和地图上工作(通过转换)。多亏了Streams,您可以摆脱代码中几乎所有的循环!
可选项(Java 8)
Java中的另一个常见问题是空指针异常。因此,Java引入了Optional —一个monad,它包装了一个可能为null或不为null的引用。可以通过功能性方式将更新应用于此Optional:
Optional.of(new Random().nextInt(10))
.filter(i -> i % 2 == 0)
.map(i -> "number is even: " + i)
.ifPresent(System.out::println);
> number is even: 6
在上面的代码段中,我们创建一个随机数,将其包装在Optional对象中,然后仅打印偶数。
JShell(Java 9)
最后,我们有一个Java的REPL,它的名字叫JShell!相反,您可以一次执行一个命令,然后立即看到结果。这是一个简单的示例:
$ <JDK>/bin/jshell
jshell> System.out.println("hello world")
hello world
长期以来,熟悉JavaScript或Python之类的解释语言的人们都对REPL感到满意,但到目前为止,Java中缺少此功能。JShell允许定义变量,但也可以定义更复杂的实体,例如多行函数,类和执行循环。此外,JShell支持自动完成功能,如果您不知道给定Java类提供的确切方法,该功能会派上用场。
不可变集合的工厂方法(Java 9)
很长时间以来,Java中缺少对列表进行简单初始化的操作,但是现在已经过去了。以前,您必须执行以下操作:
jshell> List<Integer> list = Arrays.asList(1, 2, 3, 4)
list ==> [1, 2, 3, 4]
现在将其简化如下:
jshell> List<Integer> list = List.of(1, 2, 3, 4)
b ==> [1, 2, 3, 4]
列表,集合和映射存在这种(…)方法。它们都只用一行简单的代码就创建了一个不变的对象。
使用var进行类型推断(Java 10)
Java 10引入了新的var关键字,该关键字允许省略变量的类型。
jshell> var x = new HashSet<String>()
x ==> []
jshell> x.add("apple")
$1 ==> true
在上面的代码段中,编译器可以将x的类型推断为HashSet。
此功能有助于减少样板代码并提高可读性。不过,它有一些限制:您只能在方法主体内部使用var,并且编译器会在编译时推断类型,因此所有内容仍为静态类型。
单一源文件启动(Java 11)
以前,编写一个包含一个文件的简单Java程序时,必须首先使用javac编译该文件,然后使用Java运行它。在Java 11中,您可以使用一个命令完成两个步骤。
首先,定义单个源文件Main.java:
public class Main {
public static void main(String[] args) {
System.out.println("hello world");
}
}
现在,您可以一步编译并运行它:
$ java ./Main.java
hello world
对于仅由一个Java类组成的简单启动程序或实验,此用于启动单个源文件的功能将使您的生活更轻松。