最近学习了一下scala,对scala做了一些学习后总结了一些心得,跟大家分享一下: 首先,scala基于java,是一种JVM语言,跟java一样,都是通过编译器编译成class文件,由java解释器解析执行,其核心与java一样,都是运行在java虚拟机上。从语法和特性层面,scala除了具备java的面向对象基本特性(继承、封装、多态)以外,增加了函数式编程特性,而且scala语法比java更灵活,scala编程效率要比java高很多,特别是增加了许多数据操作的函数,用起来非常爽,另外scala对java的一些数据结构进行了优化提升,期性能提升不少。同样scala程序灵活易用的同时其可读性就大大降低,特别是一个初学scala的新鸟看一个scala老鸟程序的时候感觉无从下手(这点本人深有体会),当然关于这一块的讨论,网上众说纷纭,我们就不再多扯了,下面是我个人总结的一些java和scala特点对比
下面通过以下几点深入对比一下Java和Scala都有哪些异同点
1.是否相等
写过java代码的同学都知道,java对象比较有“==”和equals两种方法,“==”符号用于对象引用地址比较,equals方法默认实现与“==”相等,如果想要对比两个对象的值必须重写Object的equals方法,java的String类重写了equals方法(当然String在使用的时候也有很多注意事项,后续在做扩展)。
package com.eoi.test.scala.equals; public class JavaEquals { public static void main(String args[]) { String aaa = "aaa"; String bbb = "aaa"; String ccc = new String("aaa"); System.out.println(aaa == bbb); System.out.println(aaa.equals(bbb)); System.out.println(aaa == ccc); System.out.println(aaa.equals(ccc)); UserBean bean1 = new UserBean("jack", 20); UserBean bean2 = new UserBean("jack", 20); System.out.println(bean1.equals(bean2)); System.out.println(bean1 == bean2); EmptyBean emptyBean1 = new EmptyBean(); EmptyBean emptyBean2 = new EmptyBean(); System.out.println(emptyBean1.equals(emptyBean2)); System.out.println(emptyBean1 == emptyBean2); } } class EmptyBean { } class UserBean { private String name; private int age; UserBean(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object obj) { if (obj instanceof UserBean) { UserBean bean = (UserBean) obj; return name.equals(bean.name) && age == bean.age; } return false; } } 运行结果: true true false true true false false false
scala语言里“==”和equals都是用于对象值比较,scala新增了“eq”和“ne”两个方法,比较两个对象的引用地址是否相同,例如代码:
case class User(name:String, age: Int) class User2(name:String, age: Int) object ScalaEquals { def main(args: Array[String]): Unit = { val aaa = "bbb" val bbb = "bbb" var ccc = "ccc1" var ddd = "ccc2" println("=============String compare=========") println(aaa == bbb) println(aaa.equals(bbb)) println(aaa.eq(bbb)) println(ccc == ddd) println(ccc.equals(ddd)) println(ccc.eq(ddd)) ddd = "ccc1" println("=============compare after value changed =========") println(ccc == ddd) println(ccc.equals(ddd)) println(ccc.eq(ddd)) val eee = new String("111") val fff = new String("111") var ggg = new String("222") var hhh = new String("222") println("============= compare new String ========") println(eee == fff) println(eee.equals(fff)) println(eee.eq(fff)) println(ggg == hhh) println(ggg.equals(hhh)) println(ggg.eq(hhh)) val jack = new User("jack", 21) val jack2 = new User("jack", 21) val jack3 = new User("jack", 20) val jack4 = jack println("==========cass class compare============") println(jack == jack2) println(jack.equals(jack2)) println(jack.eq(jack2)) println(jack == jack3) println(jack.equals(jack3)) println(jack.eq(jack3)) println(jack == jack4) println(jack.equals(jack4)) println(jack.eq(jack4)) val jack5 = new User2("jack", 21) val jack6 = new User2("jack", 21) val jack7 = new User2("jack", 20) val jack8 = jack5 println("============class compare============") println(jack5 == jack6) println(jack5.equals(jack6)) println(jack5.eq(jack6)) println(jack5 == jack7) println(jack5.equals(jack7)) println(jack5.eq(jack7)) println(jack8 == jack6) println(jack8.equals(jack6)) println(jack8.eq(jack6)) } } 运行结果: =============String compare========= true true true false false false =============compare after value changed ========= true true true ============= compare new String ======== true true false true true false ==========cass class compare============ true true false false false false true true true ============class compare============ false false false false false false false false false
从上面的例子中可以看出,User和User2的对比结果完全不一样,因为一个是case class 一个是 class,透过现象看本质,我们两个类的class文件反编译以后可以看到,User2
import scala.reflect.ScalaSignature; public class User2 { public User2(String name, int age) {} }User编译后生成两个class文件,User.class和User$.class,User.class里面重写了equals、hashCode等方法,User.class方法的实际调用时User$.class里的MODULE$
package com.eoi.test.scala.equals; import scala.Function1; import scala.Option; import scala.Product; import scala.Product.class; import scala.Serializable; import scala.Tuple2; import scala.collection.Iterator; import scala.reflect.ScalaSignature; import scala.runtime.BoxesRunTime; import scala.runtime.ScalaRunTime.; import scala.runtime.Statics; public class User implements Product, Serializable { private final String name; public User(String name, int age) { Product.class.$init$(this); } /* Error */ public boolean equals(Object x$1) { // Byte code: // 0: aload_0 // 1: aload_1 // 2: if_acmpeq +90 -> 92 // 5: aload_1 // 6: astore_2 // 7: aload_2 // 8: instanceof 2 // 11: ifeq +8 -> 19 // 14: iconst_1 // 15: istore_3 // 16: goto +5 -> 21 // 19: iconst_0 // 20: istore_3 // 21: iload_3 // 22: ifeq +74 -> 96 // 25: aload_1 // 26: checkcast 2 com/eoi/test/scala/equals/User // 29: astore 4 // 31: aload_0 // 32: invokevirtual 53 com/eoi/test/scala/equals/User:name ()Ljava/lang/String; // 35: aload 4 // 37: invokevirtual 53 com/eoi/test/scala/equals/User:name ()Ljava/lang/String; // 40: astore 5 // 42: dup // 43: ifnonnull +12 -> 55 // 46: pop // 47: aload 5 // 49: ifnull +14 -> 63 // 52: goto +36 -> 88 // 55: aload 5 // 57: invokevirtual 113 java/lang/Object:equals (Ljava/lang/Object;)Z // 60: ifeq +28 -> 88 // 63: aload_0 // 64: invokevirtual 56 com/eoi/test/scala/equals/User:age ()I // 67: aload 4 // 69: invokevirtual 56 com/eoi/test/scala/equals/User:age ()I // 72: if_icmpne +16 -> 88 // 75: aload 4 // 77: aload_0 // 78: invokevirtual 115 com/eoi/test/scala/equals/User:canEqual (Ljava/lang/Object;)Z // 81: ifeq +7 -> 88 // 84: iconst_1 // 85: goto +4 -> 89 // 88: iconst_0 // 89: ifeq +7 -> 96 // 92: iconst_1 // 93: goto +4 -> 97 // 96: iconst_0 // 97: ireturn // Line number table: // Java source line #3 -> byte code offset #0 // Local variable table: // start length slot name signature // 0 98 0 this User // 0 98 1 x$1 Object } public String toString() { return ScalaRunTime..MODULE$._toString(this); } public int hashCode() { int i = -889275714;i = Statics.mix(i, Statics.anyHash(name()));i = Statics.mix(i, age());return Statics.finalizeHash(i, 2); } public boolean canEqual(Object x$1) { return x$1 instanceof User; } public Iterator<Object> productIterator() { return ScalaRunTime..MODULE$.typedProductIterator(this); } public Object productElement(int x$1) { int i = x$1; switch (i) { default: throw new IndexOutOfBoundsException(BoxesRunTime.boxToInteger(x$1).toString()); case 1: break; } return name(); } public int productArity() { return 2; } public String productPrefix() { return "User"; } public int copy$default$2() { return age(); } public String copy$default$1() { return name(); } public User copy(String name, int age) { return new User(name, age); } public int age() { return this.age; } public String name() { return this.name; } public static Function1<String, Function1<Object, User>> curried() { return User..MODULE$.curried(); } public static Function1<Tuple2<String, Object>, User> tupled() { return User..MODULE$.tupled(); } public static User apply(String paramString, int paramInt) { return User..MODULE$.apply(paramString, paramInt); } public static Option<Tuple2<String, Object>> unapply(User paramUser) { return User..MODULE$.unapply(paramUser); } }
package com.eoi.test.scala.equals; import scala.None.; import scala.Option; import scala.Serializable; import scala.Some; import scala.Tuple2; import scala.runtime.AbstractFunction2; import scala.runtime.BoxesRunTime; public final class User$ extends AbstractFunction2<String, Object, User> implements Serializable { public static final MODULE$; private User$() { MODULE$ = this; } private Object readResolve() { return MODULE$; } public Option<Tuple2<String, Object>> unapply(User x$0) { return x$0 == null ? None..MODULE$ : new Some(new Tuple2(x$0.name(), BoxesRunTime.boxToInteger(x$0.age()))); } public User apply(String name, int age) { return new User(name, age); } public final String toString() { return "User"; } static { new (); } }
总结,Scala中的case class自动重写了equals和hashCode方法,所以实现了直接的值对比
相关推荐
该游戏基于控制台,并且在Java和Scala中均已实现。 指示 Java 只需使用javac命令编译源代码。 使用java命令运行字节码。 Scala 使用sbt进行项目建设。 直接编译文件的scalac可能不起作用。 该代码库使用支持scala...
为Java,Scala,Scala.macro,Scala.js,Scala.native,Eclipse和Maven构建集成器。 安装 生产发布 开发发布 适用于Scala IDE 4.7的Scalor插件1.X 相似的插件 入门 设置 建立并研究 插件功能 Scala 新增量 使用...
介绍 通过使用三种不同语言编写来编写...项目分为三个模块,分别用Java,Python,Scala编写逻辑相同的分词词频统计程序,比较其编写难度及运行效率。 三个模块分别为: wordCountJava wordCountPython wordCountScala
22.1 在Scala代码中使用Java名称 430 22.2 Java泛型与Scala泛型 430 22.3 JavaBean的性质 432 22.4 AnyVal类型与Java原生类型 433 22.5 Java代码中的Scala名称 433 22.6 本章回顾与下一章提要 434 ...
Java和Scala客户端共享相同的基础库 。 支持挂钩进行统计报告。 文献资料 Javadocs和Scaladocs托管在GitHub上: 每种语言的详细文档: 依存关系 共享 用于JSON解析。 Java Java 11 Scala Scala 2.11.x Scala 2.12...
2、选择需要修改的 类 安装 相同的 路径 拷贝到 src 路径下 执行一个 main 方法 进行输出 3、这时候 out 路径下 会有一个 一模一样的 class 文件 这个文件是修改以后的文件 再将 main 方法去掉 后 再 执行 Build ...
8.12 对象相等性 L1 114 8.13 值类 L2 116 练习 117 第9章 文件和正则表达式 A1 121 9.1 读取行 121 9.2 读取字符 122 9.3 读取词法单元和数字 123 9.4 从URL或其他源读取 124 9.5 读取二进制文件 124 9.6 ...
Scala 语言衍生自 Funnel 语言。Funnel 语言尝试将函数式编程和 Petri 网结合起来,而 Scala 的预期目标是将...本文希望通过一系列 Java 与 Scala 语言编写的相同程序代码的对比,让读者能够尽快地熟悉 Scala 语言。
此项目是提供开源车牌识别系统的java,scala,python,nodejs,go语言(windows和linux)调用的简单接口 EasyPR()()为此工程的子模块,没有做任何修改 替换EasyPR中的对应同名的源代码文件,不然无法加载自己定义的路径的...
java8 看不到源码锻炼追踪器 这是函数式编程技术如何改进 Vaadin UI 代码的演示。 这是通过三个应用程序 UI 实现的: 包含使用 Vaadin 7 和 Java 7 的起点。 包含利用 Java 8 中可用的各种改进的改进版本。 使用库在...
99乘法表java源码 S-99: Ninety-Nine Scala Problems 引用自 Phil Gold 的 99个 Scala 问题 的灵感是从在瑞士伯尔尼大学应用科学系的 Werner Hett 撰写的 99个 Prolog 问题 的得来来的,并且把它修改得更适合 Scala ...
为了使用Try您需要调用Try.apply(FailableSupplier)方法,该方法提供一个lambda,该lambda具有与常见java.util.function.Supplier相同的签名。 实际上, FailableSupplier只是一个java.util.function.Supplier ,在...
烟尘Soot 和其他实用程序的 Scala 包装器。 它具有以下特点: ScalaWrappers:许多隐式类提供遵循 Scala 习惯用法的方法,而不是主要的 Soot 类。... 这是正常的,旨在成为与上述相同的多模块构建的一部分。
还可以简单地消除Scala XML的许多难点,是否要更改属性? 只需在Element上执行即可。 要与名称空间匹配,为什么不呢? 所有名称访问权限都是完全合格的。 想要通过路径转换所有符合条件的孩子,这也可以。 如果您对...
Scala语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特质(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait声明。理解trait等价于(interface+abstract class)。 1.trait的声明...
已经存在许多用于相同目的的库,例如scala/pickling upickle 、 upickle 、 spray-json面向 Scala 和FasterXML/jackson 、 gson以及您可能在 Scala 中使用的许多其他 Java 库。 json-binders主要特点是: 没有运行时...
bigquery-fake-client在RDB后端(H2,PostgreSQL)的帮助下模仿Google的BigQuery,可用于在本地或CI中测试Scala / Java应用程序。 它与具有相同的API,因此在假冒和真实的之间切换非常简单。 安装 将此添加到您的...
语法处理上和Java类似,但是又不尽相同 Java异常处理回顾 try { // 可疑代码 int i = 0; int b = 10; int c = b / i; // 执行代码时,会抛出ArithmeticException异常 } catch(Exception e) {
java容器源码与Docker的持续集成 ## # ## 概述 抽象的 持续集成中的一个主要问题是,确保一旦部署的构建工件在以后的部署方案中永远不会改变。 许多开发周期需要较短的启动时间和快速的部署方式。 虚拟化工具...
Scala TON客户端 社区链接: Scala TON Client是绑定到的简单scala。 特征: TON SDK v 1.12.0的所有方法均已实现,但debot功能除外 通过同步异步调用与TON SDK进行交互 每个方法都包含inline-doc 自动下载适用...