最近学习了一下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方法,所以实现了直接的值对比
相关推荐
标题中的"一个基于Spring Boot的Spark开发手脚架(Java+Scala),开箱即用!模拟了1个WordCount.zip"表明这是一个使用Spring Boot框架构建的Spark应用程序,它结合了Java和Scala两种编程语言,旨在提供一个快速启动...
这样,Scala 就会正确地将数组的每个元素拆分成单独的参数,从而达到与 Java 相同的调用效果。如果变参方法的类型是 `Object...`,那么在 Scala 中调用时,如果没有使用 `:_*`,可能会导致运行时的错误,因为 Scala ...
【Java与Scala的性能优化与特性对比】 在编程领域,性能优化是提升应用程序效率的关键步骤。Java和Scala都是广泛使用的编程语言,它们各自有其独特的性能优化策略。以Java为例,一个良好的日志实践是在输出时进行...
虽然Scala是基于Java的,但Scala提供了一套与Java不同的语法和类库,这要求学习Scala的开发者了解其与Java的相同点和不同点。 为了使用Scala进行开发,需要进行环境搭建。这包括安装Java开发工具包(JDK)版本1.8或...
该游戏基于控制台,并且在Java和Scala中均已实现。 指示 Java 只需使用javac命令编译源代码。 使用java命令运行字节码。 Scala 使用sbt进行项目建设。 直接编译文件的scalac可能不起作用。 该代码库使用支持scala...
在学习Scala语言时,需要搞清楚Scala和Java之间的关系,将Scala和Java的相同点和不同点搞清楚,就可以快速的掌握Scala这门语言。 大数据技术之Scala是指利用Scala语言来处理和分析大数据的一种技术。Scala语言的...
Scala的数据类型与Java基本相同,但Scala支持更多类型的自动转换。 - **运算符**:支持常见的算术、比较和逻辑运算符。 - **字符串操作**: - 字符串可以通过双引号包围的方式声明。 - 支持字符串插值,通过前缀...
Scala和Clojure都是现代函数式编程语言,它们都运行在Java虚拟机(JVM)上,能够利用Java的生态系统和资源。Scala是一种多范式语言,结合了面向对象和函数式编程的特点,提供了强大的类型系统和模式匹配功能。...
为Java,Scala,Scala.macro,Scala.js,Scala.native,Eclipse和Maven构建集成器。 安装 生产发布 开发发布 适用于Scala IDE 4.7的Scalor插件1.X 相似的插件 入门 设置 建立并研究 插件功能 Scala 新增量 使用...
- **简洁**: 与Java相比,Scala通常需要更少的代码行来完成相同的功能。 - **与Java的互操作性**: Scala可以在JVM上运行,并且能够无缝地调用Java库。 #### 二、Scala安装与运行 ##### 1. JDK安装 - **Windows*...
介绍 通过使用三种不同语言编写来编写...项目分为三个模块,分别用Java,Python,Scala编写逻辑相同的分词词频统计程序,比较其编写难度及运行效率。 三个模块分别为: wordCountJava wordCountPython wordCountScala
#### 一、Scala简介与特性 **标题与描述解析:** - **标题**:“Scala 教程”明确指出这是一份关于Scala编程语言的学习指南。 - **描述**:“Scala 教程 .pdf”进一步强调这份教程是以PDF格式提供的。 **标签解析...
1. **Java与Scala的互操作性**:Scala代码可以直接调用Java库,并且Scala和Java代码可以在同一个项目中混合编写。 2. **类型推断**:Scala允许程序员省略变量或方法的显式类型声明,编译器能够自动推断出正确的类型...
Scala SDK 2.12.3 是一个针对Java平台的多范式编程语言的软件开发工具包,它提供了丰富的库和编译器,用于构建高效、可扩展的应用程序。Scala结合了面向对象和函数式编程的概念,使得它在处理并发和大数据分析等领域...
Scala是一种现代的多范式编程语言,集成了面向对象编程和函数式编程的特性。本篇知识点将围绕Scala中文版书籍所提及的关键概念,重点介绍Scala入门基础的各个方面。Scala旨在提供简洁且表达力强的方式来编写程序,...
总之,Scala 是一种功能强大的编程语言,它不仅适用于 Java 开发者的迁移学习,也为其他编程语言的学习者提供了新的编程思路和技术栈的选择。通过不断探索和实践,你可以充分利用 Scala 的优点,提高开发效率和软件...
特质(Trait)是Scala的另一特色,类似Java的接口,但可以包含实现。特质可以用来实现多重继承,允许一个类实现多个行为。这在设计上提供了更大的自由度,避免了经典Java中的"菱形问题"。 枚举类在Scala中可以定义...
- **while** 和 **do-while** 循环与Java相同。 - **for循环** 和 **foreach循环** 用于迭代。 - for循环支持多种写法,可以使用 `yield` 关键字生成新的集合。 - foreach循环适用于遍历集合,可以接收其他函数...
Scala 是一种静态类型的、面向对象和函数式的编程语言,它运行在 Java 平台上,利用了 JVM 的强大功能。TypeScript 则是 JavaScript 的超集,添加了静态类型和其他高级特性,用于构建大型、可维护的前端应用程序。 ...