【转】Java 12 特性及更新

原文链接

前言

Java 12(发布于2019年3月19日)是JDK的最新版本。让我们看看它为开发人员和架构师带来的新特性和改进。

正文

Stream API 新的方法 Collectors.teeing()

此收集器将其输入转发给其他两个收集器,然后将它们的结果与一个函数合并。它是一个静态方法Collectors::teeing.

teeing(Collector, Collector, BiFunction) 接受两个收集器和一个函数来合并它们的结果。传递给结果收集器的每个元素都由两个下游收集器处理,然后使用指定的merge函数将它们的结果合并到最终结果中。

例如,在给定的雇员列表中,如果我们想要找出拥有最高工资和最低工资的雇员,我们可以使用此收集器在单个语句中完成。

1
2
3
4
5
6
SalaryRange salaryRange = Stream
.of(56700, 67600, 45200, 120000, 77600, 85000)
.collect(teeing(
minBy(Integer::compareTo),
maxBy(Integer::compareTo),
SalaryRange::fromOptional));

关于更多的关于此收集器的内容,可以查看Collectors.teeing()这篇文章。

String API 变化

String.indent()

这个缩进方法有助于更改字符串的缩进。我们可以传递一个正值,也可以传递一个负值,这取决于我们是想要添加更多的空白还是删除现有的空白。

1
2
3
4
5
6
7
String result = "foo\nbar\nbar2".indent(4);

System.out.println(result);

// foo
// bar
// bar2

需要注意,indent()方法会自动添加新行字符(如果没有的话)。这是意料之中的,也是新方法的一个特点。

每个空白字符都被视为单个字符。特别是制表符"\t" (U+0009)被认为是单个字符;它没有展开。

String.transform()

transform()方法获取一个字符串,并在函数的帮助下将其转换为一个新字符串。

在给定的示例中,我们有一个名称列表。我们使用transform()方法执行两个操作(删除空白和将所有名称设置为大小写)。

1
2
3
4
5
6
7
8
9
10
11
12
13
List<String> names = List.of(
" Alex",
"brian");

List<String> transformedNames = new ArrayList<>();

for (String name : names)
{
String transformedName = name.transform(String::strip)
.transform(StringUtils::toCamelCase);

transformedNames.add(transformedName);
}

String constants

从Java 12开始,String类实现了两个额外的接口java.lang.constant.Constablejava.lang.constant.ConstantDesc

String类还引入了另外两个低级方法describeConstable()resolveConstantDesc(MethodHandles.Lookup)

它们是低级api,用于库和提供字节码解析和生成功能的工具,例如Byte Buddy。

注意,Constable类型的值是常量,可以在JVMS 4.4中描述的Java类文件的常量池中表示,它的实例可以在名义上将自己描述为ConstantDesc

resolveConstantDesc()类似于describeConstable(),不同之处在于这个方法返回的是ConstantDesc的一个实例。

Files.mismatch(Path, Path)

有时,我们希望确定两个文件是否具有相同的内容。这个API有助于比较文件的内容。

mismatch()方法比较两个文件路径并返回一个long值。long值表示两个文件内容中第一个不匹配的字节的位置。如果文件内容相同,返回值将是“-1”。

1
2
3
4
5
Path helloworld1 = tempDir.resolve("helloworld1.txt");

Path helloworld2 = tempDir.resolve("helloworld2.txt");

long diff = Files.mismatch(helloworld1, helloworld2); //returns long value

数字格式

由用户界面或命令行工具呈现的大数字总是很难解析。使用数字的缩写形式要普遍得多。紧凑的数字表示更易于阅读,并且在不丢失原始含义的情况下,在屏幕上需要更少的空间。

例: 3.6 M3,600,000 容易读得多。

Java 12引入了一个NumberFormat.getCompactNumberInstance(Locale, NumberFormat.Style)的方便方法用于创建紧凑数字表示。

1
2
3
4
NumberFormat formatter = NumberFormat.getCompactNumberInstance(Locale.US,
NumberFormat.Style.SHORT);

String formattedString = formatter.format(25000L); //25K

Unicode 11 相关支持

在一个emoji表情符号在社交媒体渠道上扮演着重要角色的时代,支持最新的Unicode规范比以往任何时候都更重要。Java 12保持了同步并支持Unicode 11。

Unicode 11增加了684个字符,总共有137374个字符,还有7个新脚本,总共有146个脚本。

switch 表达式扩展

这个更改扩展了switch语句,因此它既可以用作语句,也可以用作表达式。

我们可以简单地使用箭头语法,而不必为每个case块定义一个break语句。箭头语法在语义上看起来像一个lambda,它将大小写标签从表达式中分离出来。

使用新的switch表达式,我们可以直接将switch语句分配给一个变量。

1
2
3
4
5
6
7
8
9
10
boolean isWeekend = switch (day) 
{
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> false;

case SATURDAY, SUNDAY -> true;

default -> throw new IllegalStateException("Illegal day entry :: " + day);
};

System.out.println(isWeekend);//根据输入日期返回true或false

要使用此特性,请记住,我们必须在应用程序启动期间使用-enable-preview标志显式地指示JVM。

结语

以上就是关于Java 12 的全部内容。




-------------文章结束啦 ~\(≧▽≦)/~ 感谢您的阅读-------------

您的支持就是我创作的动力!

欢迎关注我的其它发布渠道