移位操作提高代码的可读性
Java 14带有Records的预览语言功能—一种特殊的轻量级类,可以与其他语言中的类似构造进行比较,例如C#中的record
类,Kotlin中的data
类和Scala中的case
类。
A)已经有许多博客文章解释Java 14记录,B)大量文章将记录的用法与Project Lombok的@Value
(用于创建不可变的类)进行了比较,因此在此我不再赘述。
Brian Goetz在JEP 384:记录中进行了解释(第二,预览它们背后的动机和规则,例如对记录声明的限制以及与“正常”类的相似性。
我注意到了当地的记录 :
产生和使用记录的程序可能会处理许多本身就是简单变量组的中间值。 声明记录以对那些中间值建模通常会很方便。 一种选择是声明静态且嵌套的“帮助程序”记录,就像今天许多程序声明帮助程序类一样。 一个更方便的选择是在方法内部声明一条记录,该记录靠近操纵变量的代码。 因此,该JEP提出了类似于本地类的传统构造的本地记录。
在以下示例中,将使用本地记录MerchantSales对商人和每月销售额的汇总进行建模。 使用此记录可提高以下流操作的可读性:
下面的MerchantSales
是一个可变的元组,既包含单个Merchant
又包含在处理流时计算的销售额。 我们需要同时捕获两者 ,以便能够对计算出的销售额进行排序 ,但最终返回该销售额的(原始)商人。
List findTopMerchants(List merchants, int month) {
// Local record
record MerchantSales(Merchant merchant, double sales) {}
return merchants.stream()
.map(merchant -> new MerchantSales(merchant, computeSales(merchant, month)))
.sorted((m1, m2) -> Double.compare(m2.getSales(), m1.getSales()))
.map(MerchantSales::getMerchant)
.collect(toList()); }
这是在方法中定义的记录这一事实使它成为本地记录,我可以立即认识到在许多Stream API情况下的优势,在这种情况下,流需要累积许多分组在一起的值:如示例所示,映射X,计算或生成Y并在流中的后续步骤中同时保留两者。
当然,在所有这些情况下,我显然都通过引入了辅助POJO或重新设计了整个流逻辑来解决了这一问题,但是阅读JEP使我记住Java支持局部类 (不是记录 ;我的意思是普通类 )。从一开始就差不多。
局部类是非静态的,因为它们可以访问封闭块的实例成员。
本地记录和本地(内部)类增加了封装的使用。 您无需使类型在创建它的块之外更广泛地可用。
这是本地类的示例。 我正在使用Lombok的@Data
生成必需的参数构造函数和getters / setter,以保持较少冗长的精神,但是您始终可以使用纯原始Java。
List findTopMerchants(List merchants, int month) {
// Local class
@Data class MerchantSales {
final Merchant merchant;
final double sales;
}
return merchants.stream()
.map(merchant -> new MerchantSales(merchant, computeSales(merchant, month)))
.sorted((m1, m2) -> Double.compare(m2.getSales(), m1.getSales()))
.map(MerchantSales::getMerchant)
.collect(toList()); }
因此,当尚未使用Java 14时,或者无法启用记录预览功能时,可以始终使用本地类来提高流操作的可读性。
51.825217
5.812153
奈梅亨,荷兰
翻译自: https://www.javacodegeeks.com/2020/06/local-records-or-classes-to-improve-the-readability-of-stream-operations.html
移位操作提高代码的可读性