java scala

因此,我正在尝试使用Scala,因为我想编写一个解析器,而Scala Parsers API似乎非常合适。 毕竟,我可以在Scala中实现解析器并将其包装在Java接口后面,因此除了附加的运行时依赖关系之外,应该不存在任何互操作性问题。

在几天后真正真正地习惯了Scala语法的强大功能之后,以下是我回到编写Java时最想错过的十件事:

1.多行字符串

这是我个人的最爱,也是一种非常棒的功能,应该使用任何语言。 甚至PHP都有:多行字符串。 像编写一样简单:

println ("""Dear reader,If we had this feature in Java,
wouldn't that be great?Yours Sincerely,
Lukas""")

这在哪里有用? 使用SQL,当然! 这是使用jOOQ和Scala运行纯SQL语句的方法:

println(DSL.using(configuration).fetch("""SELECT a.first_name, a.last_name, b.titleFROM author aJOIN book b ON a.id = b.author_idORDER BY a.id, b.id""")
)

这不仅对静态字符串有用。 使用字符串插值,您可以轻松地将变量注入到这样的字符串中:

val predicate =if (someCondition)"AND a.id = 1"else""println(DSL.using(configuration)// Observe this little "s".fetch(s"""SELECT a.first_name, a.last_name, b.titleFROM author aJOIN book b ON a.id = b.author_id-- This predicate is the referencing the-- above Scala local variable. Neat!WHERE 1 = 1 $predicateORDER BY a.id, b.id""")
)

太棒了,不是吗? 对于SQL,Scala具有很大的潜力。

2.分号

我真心没有错过他们一点。 我构造代码的方式(可能也是大多数人构造代码的方式),Scala似乎根本不需要分号。 在JavaScript中,我不会说同样的话。 JavaScript的解释性和非类型安全性质似乎表明,放弃可选的语法元素可以保证您一臂之力。 但是Scala不支持。

val a = thisIs.soMuchBetter()
val b = no.semiColons()
val c = at.theEndOfALine()

可能是由于Scala的类型安全性导致的,这将使编译器在那些罕见的模棱两可的情况下抱怨,但这只是有根据的猜测。

3.括号

这是一个雷区,在许多情况下,省略括号似乎很危险。 实际上,在调用方法时,您也可以忽略这些点:

myObject method myArgument

由于可能会产生大量歧义,尤其是在链接更多方法调用时,我认为最好避免使用此技术。 但是在某些情况下,“忘记”父母是很方便的。 例如

val s = myObject.toString

4.类型推断

这在Java中确实很烦人,与此同时,似乎许多其他语言也都做到了这一点。 Java仅具有有限的类型推断功能,并且事情并不尽如人意 。

在Scala中,我可以简单地写:

val s = myObject.toString

……而不在乎s是String类型的事实。 有时但仅在某些时候,我想明确指定引用的类型。 在那种情况下,我仍然可以做到:

val s : String = myObject.toString

5.案例分类

我想我想写另一个POJO,它具有40个属性,构造函数,getter,setter,equals,hashCode和toString

-没人说。 曾经

Scala具有案例类。 用单线编写的简单不可变的pojos。 以Person案例类为例:

case class Person(firstName: String, lastName: String)

我同意,必须确实写下一次属性。 但是其他一切应该是自动的。

以及如何创建此类案例类的实例? 轻松,你甚至都不需要new运营商(事实上,它完全逃脱了我的想象,为什么new真正需要摆在首位):

Person("George", "Orwell")

而已。 您还想写些什么以符合企业标准?

边注

好的,现在有些人会争辩说要使用lombok项目 。 基于注释的代码生成是胡说八道,应最好避免。 实际上,Java生态系统中的许多注释简单地证明了Java语言的(而且将永远是)其进化能力非常有限这一事实。 以@Override为例。 这应该是关键字,而不是注释。 您可能会认为这是表面上的区别,但是我说Scala已经证明注释几乎总是错误的工具。 还是您最近看过带有大量注释的 Scala代码?

6.到处都有方法(功能!)

我认为,这实际上是任何语言中最有用的功能之一。 为什么我们总是必须将方法链接到特定的类? 为什么我们不能简单地拥有任何作用域级别的方法? 因为我们可以,所以使用Scala:

// "Top-level", i.e. associated with the package
def m1(i : Int) = i + 1object Test {// "Static" method in the Test instancedef m2(i : Int) = i + 2def main(args: Array[String]): Unit = {// Local method in the main methoddef m3(i : Int) = i + 3println(m1(1))println(m2(1))println(m3(1))}
}

对? 为什么我不能在另一个方法中定义本地方法? 我可以使用Java中的类来做到这一点:

public void method() {class LocalClass {}System.out.println(new LocalClass());
}

局部类是方法局部的内部类。 这几乎没有用,但是真正有用的是局部方法。

JavaScript或REPL也支持这些功能。 这对于在应用程序范围之外测试小型算法或概念非常有用。

在Java中,我们通常倾向于这样做:

public class SomeRandomClass {// [...]public static void main(String[] args) {System.out.println(SomeOtherClass.testMethod());}// [...]
}

在Scala中,我将在REPL中编写以下代码:

println(SomeOtherClass.testMethod)

还请注意始终可用的println方法。 纯金方面高效的调试。

8.数组不是(很多)特例

在Java中,除了基本类型之外,还有一些我们称为数组的怪异事物。 数组起源于一个完全独立的宇宙,在这里我们必须记住起源于柯克上尉(大约)时代的古怪规则:

是的,规则如下:

// Compiles but fails at runtime
Object[] arrrrr = new String[1];
arrrrr[0] = new Object();// This works
Object[] arrrr2 = new Integer[1];
arrrr2[0] = 1; // Autoboxing// This doesn't work
Object[] arrrr3 = new int[];// This works
Object[] arr4[] = new Object[1][];// So does this (initialisation):
Object[][] arr5 = { { } };// Or this (puzzle: Why does it work?):
Object[][] arr6 = { { new int[1] } };// But this doesn't work (assignment)
arr5 = { { } };

是的,清单可以继续。 从语法上讲,使用Scala,数组不再是一种特殊情况:

val a = new Array[String](3);
a(0) = "A"
a(1) = "B"
a(2) = "C"
a.map(v => v + ":")// output Array(A:, B:, C:)

如您所见,数组的行为与其他集合非常相似,包括可以在其上使用的所有有用方法。

9.符号方法名称

现在,这个话题更具争议性,因为它使我们想起了运算符重载的危险 。 但是,每隔一段时间,我们希望有类似的东西。 可以让我们写的东西:

val x = BigDecimal(3);
val y = BigDecimal(4);
val z = x * y

非常直观地,z的值应为BigDecimal(12) 。 那不能太难,对吗? 我不在乎*的实现是否真的是一个称为multiply()的方法。 写下该方法时,我想使用看起来很普通的运算符进行乘法。

顺便说一句,我也想用SQL做到这一点。 这是一个例子:

select ( AUTHOR.FIRST_NAME || " " || AUTHOR.LAST_NAME,AUTHOR.AGE - 10
)
from AUTHOR
where AUTHOR.ID > 10
fetch

那没有道理吗? 我们知道|| 表示concat(在某些数据库中)。 我们知道- (减号)和> (大于)的含义。 为什么不就写呢?

上面是在Scala中的jOOQ的编译示例。

注意:警告

允许操作符重载或符号方法名之类的东西总是存在弊端。 它可能(并将被)滥用。 图书馆与Scala语言本身一样多 。

10.元组

作为一个SQL人员,这再次是我在其他语言中最想念的功能之一。 在SQL中,所有内容都是TABLE或ROW。 实际上,很少有人知道这一点 ,并且很少有数据库实际上支持这种思维方式。

Scala没有ROW类型(实际上是记录),但是至少有匿名元组类型。 将行视为具有命名属性的元组,而案例类将命名为行:

  • 元组:具有类型化和索引元素的匿名类型
  • 行:具有类型化,命名和索引元素的匿名类型
  • 案例类:具有类型化元素和命名元素的命名类型

在Scala中,我可以这样写:

// A tuple with two values
val t1 = (1, "A")// A nested tuple
val t2 = (1, "A", (2, "B"))

在Java中,可以完成类似的操作,但是您必须自己编写该库,并且不提供语言支持:

class Tuple2<T1, T2> {// Lots of bloat, see missing case classes
}class Tuple3<T1, T2, T3> {// Bloat bloat bloat
}

然后:

// Yikes, no type inference...
Tuple2<Integer, String> t1 = new Tuple2<>(1, "A");// OK, this will certainly not look nice
Tuple3<Integer, String, Tuple2<Integer, String>> t2 =new Tuple3<>(1, "A", new Tuple2<>(2, "B"));

jOOQ充分利用了上述技术,将SQL的行值表达式带到Java,并且令人惊讶的是,在大多数情况下,您可以在不丢失类型推断的情况下做到这一点,因为jOOQ是一种流利的API,在其中您从未真正将值分配给局部变量。例:

DSL.using(configuration).select(T1.SOME_VALUE).from(T1).where(// This ROW constructor is completely type saferow(T1.COL1, T1.COL2).in(select(T2.A, T2.B).from(T2))).fetch();

结论

当然,这是一篇有关scala的文章,与Java稍有抵触。 不要误会我的意思。 我绝不希望完全迁移到Scala。 我认为Scala语言远远超出了任何有用软件中的合理范围。 有很多看起来不错的小功能和头,但不可避免地会炸掉您的脸,例如:

  • implicit转换。 这不仅很难管理,而且还严重降低了编译速度。 此外,使用implicit合理地实现语义版本控制可能完全是不可能的,因为不可能通过偶然的向后不兼容预见所有可能的客户端代码损坏。
  • 乍一看,本地导入看起来很棒,但是当人们开始部分导入或重命名本地范围的类型时,它们的功能很快使代码难以理解。
  • 符号方法名称最常被滥用。 以解析器API为例,它具有诸如^^^^^^?类的方法名称^?~!

尽管如此,我认为本文中列出的Scala与Java相比的优点也可以全部用Java实现:

  • 几乎没有破坏向后兼容的风险
  • 用(可能)不太大的努力,在JLS方面
  • 对开发人员的生产力产生巨大影响
  • 对Java的竞争力产生巨大影响

无论如何,Java 9将是另一个很有前途的版本,其热门话题包括值类型, 声明站点差异 , 特殊化(非常有趣!)或ClassDynamic。

有了这些巨大的变化,我们希望上面的一些小改进还有一定的余地,这将为日常工作增加更多的直接价值。

翻译自: https://www.javacodegeeks.com/2014/08/the-10-most-annoying-things-coming-back-to-java-after-some-days-of-scala.html

java scala

java scala_经过几天的Scala回归Java的10个最烦人的事情相关推荐

  1. 经过几天的Scala回归Java的10个最烦人的事情

    因此,我正在尝试使用Scala,因为我想编写一个解析器,而Scala Parsers API似乎非常合适. 毕竟,我可以在Scala中实现解析器并将其包装在Java接口后面,因此除了附加的运行时依赖关 ...

  2. java工程引入scala_引入ReactiveInflux:用于Scala和Java的无阻塞InfluxDB驱动程序,支持Apache Spark...

    java工程引入scala 我很高兴宣布Pygmalios开发的ReactiveInflux的第一个发行版. InfluxDB错过了Scala和Java的非阻塞驱动程序. 不变性,可测试性和可扩展性是 ...

  3. java多态优化多个if_脑壳疼!代码中那么多“烦人”的if else

    if else 是我们写代码时,使用频率最高的关键词之一,然而有时过多的 if else 会让我们感到脑壳疼. 图片来自 Pexels 例如下面这个伪代码: 是不是很崩溃?虽然他是伪代码,并且看起来也 ...

  4. Scala与Java交互

    2019独角兽企业重金招聘Python工程师标准>>> ###代码示例 假如我们想要根据某个特定国家(比如法国)的习惯来获取并格式化当前日期, 我们可以使用以下 Scala 和 Ja ...

  5. Scala调用Java静态成员及静态方法注意点——只能通过当前类名调用而不能借助子类调用父类静态成员/方法

    只能通过当前类名NioUtil调用静态成员 package com.zxl.scalaimport cn.hutool.core.io.{FileUtil, IoUtil, NioUtil} impo ...

  6. 详解Scala与Java的互动

    详解Scala与Java的互动

  7. scala调用java代码_scala调用java代码

    scala调用java代码 @(SCALA)[scala] 在scala中调用java代替非常非常简单,直接调用即可 (一)一个简单示例 1.创建一个java类 package com.lujinho ...

  8. Scala与Java集合互转摘要

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  9. 如何获取Kafka的消费者详情——从Scala到Java的切换

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

最新文章

  1. matlab中decnbr,LMI 求解时调用decnbr()函数得到的决策变量的个数为小数是为什么
  2. 连接redis的linux命令,redis常见操作命令
  3. C++ Primer 5th笔记(10)chapter10 泛型算法 : read
  4. boost::gregorian模块实现使用公历精确地推进一个月的测试程序
  5. PHP网站开启gzip压缩,php中开启gzip压缩的2种方法代码
  6. Android开始中的OOM异常
  7. MarkDown数学符号(更新中)
  8. 全球第一博客---缠中说禅
  9. Node.js学习笔记(五)——WebSocket
  10. CPU的内部架构和工作原理(简介)
  11. 小熊派开发板STM32L431_BearPi_LiteOS_E53_ST1调测GPS+2G心得(附代码修正版)
  12. Addressing Failure Prediction by Learning Model Confidence
  13. 根据url生成二维码,扫描打开url的两种方法编辑器
  14. Android WiFi热点
  15. Fuzzy kmeans
  16. 利用python爬虫大量爬取网页图片
  17. 世界正游弋于开源之海,但只有 Red Hat 从中盈利
  18. 学生个人博客网页设计作品 学生个人网页模板 个人网页制作 HTML学生个人网站作业设计
  19. w7计算机读条,win7设备和打印机一直读条如何解决
  20. amazon海淘+CUL中美速递转运详细教程(免税)

热门文章

  1. nssl1157-简单数学题【约数,换元法】
  2. ssl1626-花店橱窗布置【日常dp】
  3. 【斜率优化】玩具装箱(luogu 3195)
  4. 【dfs】【链表】连通图 (ssl 1758)
  5. Codeforces274B
  6. 去 BAT 面试,总结了这 55 道 MySQL 面试题
  7. mybatis入门(二)之XML 映射配置文件
  8. 零配置 之 Spring 概述
  9. jps命令:查看Java进程等详细信息
  10. 【Servlet】获取并输出服务器获得的数据