Scala是什么
- 百度百科:Scala是一门多范式的编程语言,一种类似java的编程语言 ,设计初衷是实现可伸缩的语言 、并集成面向对象编程和函数式编程的各种特性。
- 我的理解:Scala是java的强化版,也是基于jvm的编程语言,可以直接调用所有java的库资源,同时其具备函数式编程的特性以及脚本语言的特性,语法更加简洁,功能更加强大
相比java的优点
-
优雅:这是框架设计师第一个要考虑的问题,API 是否优雅直接影响程序员的编程体验。
-
速度快:Scala 语言表达能力强,一行代码抵得上 Java 多行,开发速度快;Scala 是静态编译的, 所以和 JRuby , Groovy 比起来速度会快很多。
-
能融合到 Hadoop 生态圈:Hadoop 现在是大数据事实标准,Spark 并不是要取代 Hadoop,而是要 完善 Hadoop 生态。JVM 语言大部分可能会想到 Java,但 Java 做出来的 API 太丑,或者想实现一 个优雅的 API 太费劲。
和java的区别(以java8和Scala2.12为例)
定义变量
-
Scala用var,变量类型在后面
var s:String="蔡徐坤"
-
java 定义变量时变量类型在前面
String s="蔡徐坤";
换行符
- Scala 是面向行的语言,语句可以用分号 ; 结束或 换行符 。
- java需要用;作为换行符
数据类型
-
Scala 中的所有数据类型都是对象【即 Object 修饰的】,没有像 Java 中的基本数据类型。但是 Scala 中的数据类型也分为两大类型: AnyVal【值类型】和 AnyRef【引用类型】 。
Unit
表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有 一个实例值,写成()。
Nothing
Nothing类型在Scala的类层级的最底端;它是任何其他类型的子类型。
Any
Any是所有其他类的超类
Null
Null 类只有一个实例对象: null ,与 Java 中的 null 关键字类似。任何的 AnyRef 类型都可赋值为 null ,但是 AnyVal 不能赋值为 null 。
AnyRef
AnyRef类是Scala里所有引用类(reference class)的基类
扫描二维码关注公众号,回复: 10686760 查看本文章 -
Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
导包
-
Scala可以在任何位置导包,
import
语句用于导入其他包中的成员(类,特质,函数等)。import users._ // 导入包 users 中的所有成员 import users.User // 导入类 User import users.{User, UserPreferences} // 仅导入选择的成员 import users.{UserPreferences => UPrefs} // 导入类并且设置别名
-
java的导包相比Scala来说只是导类,并且只能在头部事先声明 。
import java.util.HashMap;
运算符
- Scala里面的运算符和java没什么区别,只是Scala中万物皆可对象,所以运算符也是对象
- Scala 不支持 三目 运算符
- Scala 不支持 ++ 、 – 操作符
返回值
- Scala 中任意表达式都是由返回值的,具体的返回结果的值取决于代码体最后一行的内容。
- java返回值需要用return进行返回
循环
Scala
-
for:Scala 也为 for 循环这一常见的循环结构提供了非常多的特性,这些 for 循环特性被称为 for 推导式或者 for 表达式。
-
to
for(i <- 1 to 10){// 循环 1 到 10 全部包含 println(s"i = $i") }
-
until
for(i <- 1 until 10){//循环 1 到 9 ,不包含 10 println(s"i = $i") }
-
Range Range 是一个范围对象,可以生成一个范围的数据
for( i <- Range(1,10)){//类似于 until println(s"i = $i") } for(i <- Range(1,10,2)){//增加步长为2,不包含10 println(s"i = $i") }
-
-
while:由于 while 循环没有返回值,所有要使用该语句来计算并返回结果的时候就必须使用外部变量,因此会导致循环体对外部变量造成污染,因此在 Scala 中不推荐使用 while ,而推荐使用 for 循环。
-
break:在 Scala 中没有 break 关键字,可以使用对象实现。
import scala.util.control.Breaks//导入相应包 for(i<-1 to 10){ if(i==5) Breaks.break//调用方法 }
java
-
for
for (int i = 0; i < args.length; i++) 括号内分别为循环变量类型 循环变量名称;循环变量的范围;循环变量进行运算{ } for (int i : integers)括号内分别为 :循环变量类型 循环变量名称 : 要被遍历的对象 { }
-
while
while (condition)括号内为循环条件 { }//使用方法:当条件表达式成立时,则执行循环体,然后再判断,依次类推,如果条件不满足,有可能一次都不执行。一般用于循环次数不确定的循环
-
do while
do { //使用方法:一般用于循环次数不确定的循环,与 while 循环不同的是 dowhile 循环先执行后判断,至少执行一次. } while (condition);括号内为循环条件
-
break:java关键字,用来跳出循环
-
continue:让程序立刻跳转到下一次循环的迭代。在 for 循环中,continue 语句使程序立即跳转到更新语句。在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。
函数
-
Scala中定义函数
def 方法名/函数名([参数列表])[[: 返回值类型] = ]{ 方法体/函数体 } //匿名函数 ([参数列表]) => {}
在调用函数时如果不需要传参数,()可以省略。
-
Scala定义可变参数函数
def f1(a:Int*)={//*代表参数数量不确定 var sum = 0 for(i<-a) sum+=i sum } print(f1(1,2,3,4,5))
-
java中定义函数
修饰符 返回值类型 函数名([参数类型1 参数名1,参数类型2 参数名2....]){ //[]里面表示可选项,即参数不是必须的 执行语句... return 返回值;//返回值的类型必须与返回值类型一致 }
调用函数时无论需不需要参数,都要加上括号
-
java中定义可变参数函数
返回值 方法名(参数类型...参数名称)//...代表参数数量不确定
-
Scala函数总结
-
函数可以有很多个参数,但是如果没有参数,那么在调用时可以不带 ()
-
函数的参数类型和返回值类型均可以是任意数据类型
-
函数的返回值类型可以根据返回值自动推断,因此返回值类型可以省略
-
函数如果指定了 return 关键字返回数据,那么返回值类型就不能省略
-
函数如果指定了返回值类型为 Unit ,那么无论是否有 return 关键字和最后一行是什 么,返回值均为 ()
-
Scala 语法中任何的语法结构都可以嵌套其他语法结构。即函数中可以嵌套类/函数等,类中 亦可嵌套其他类和函数。
-
函数可以赋值给一个变量
-
函数不可以重载
-
模式匹配
-
java中用switch和if进行模式匹配
switch(expression){ case value : //语句 break; //可选 case value : //语句 break; //可选 //你可以有任意数量的case语句 default : //可选 //语句 }
-
Scala中用match和if进行模式匹配,功能更加强大。Scala的match还可以匹配数组,类型,元祖,list等等。
val score = "A" score match { case "A"=>println("优秀") case "B"=>println("良好") case "C"=>println("及格") case _ =>println("不及格") } /* 如果所有 case 都不匹配,那么执行 case _ 分支,类似于 Java 中 default 语句 如果所有 case 都不匹配,又没有写 case _ 分支,那么会抛出 MatchError 异常 每个 case 语句都不需要 break 来中断,这点与 Java 不同 可以在 match 中使用其它类型,而不仅仅是字符串,还可以是类, Array 或者 List 的元 素等 => 类似于 Java 中 swtich 的 : => 后面的代码块到下一个 case ,是作为一个整体执行,可以使用 {} 括起来,也可以不 括 */
权限修饰符
-
java中有四种权限修饰符,默认是default
public 公共的 本类、同包、子类、当前项目中任意类的位置只要有对象都可以访问 protected 保护的 本类、同包、子类(通过子类对象在子类范围内部访问) default 默认的 本类、同包 private 私有的 本类
-
scala有三种权限修饰符,默认是公共的
公共的 是默认的访问权限,没有这个关键 public protected 只能子类访问 private 私有访问权限 private[] 包访问权限
构造方法
-
java分有参构造器和无参构造器,构造器写在类里面。
-
Scala分主构造器和辅助构造器。主构造方法写在类体上,辅助构造方法名字是this写在类里面,必须调用已有的辅助构造方法或者主构造方法。
继承
- java继承父类后可以重写父类的方法
- Scala继承父类后不仅可以重写父类的方法还可以重写父类的属性,重写父类的方法一定要加overwrite关键字
特质
-
java中没有特质,但是有接口,接口用implements继承
-
Scala中的特质,特质用extends继承。
-
Scala动态混入,在不改变以前代码的基础上,直接增加功能,拓展性非常强悍
package trait5{ trait T1{ def m(): Unit ={ println("T1 m ...") } } class C{ } object Demo extends App{ //动态混入特质 val c = new C with T1 c.m() } }
隐式转换
-
java中低级向高级转换—自动转换:隐式转换 , 高级到低级转换—强制转换
-
在 Scala 当中,要想使用隐式转换,必须标记为 implicit 关键字
implict 关键字可以用来修饰参数【隐式值与隐式参数】、函数【隐式视图】、类【隐式类】、对象【隐式对象】
在整个作用域中,隐式转换的名称必须唯一
隐式转换首先在其作用域中查找,如果当前作用域没有隐式转换,编译器就会自动到相应源或目标类型的伴生对象中查找隐式转换
Scala 中的隐式值、隐式类、隐式对象常放在单例对象 object 中
隐式转换与函数名或参数名无关,只与签名【参数类型和返回值类型】有关
隐式转换可以在不改变源码的基础上增强类的功能
集合
-
java集合主要有list,set,map。。
-
Scala主要分可变和不可变集合,然后才是list,map,set。Scala定义更多对集合的操作。
-
Scala中还有元组这个概念,相当于java中的对象类,更加方便,不需要再定义一个类。
object Demo05_Tuple { def main(args: Array[String]): Unit = { //元组:将无关的数据当成一个整体使用,那么无关的数据的整体就是一个元组 //1. 创建元组 val t1 = ("张三",17,"13526809999") //2. 访问元组 println(t1._1)//"张三" println(t1._2) println(t1) //3. 元组中的数据最多22个数据,分别对应于Tuple1,Tuple2...Tuple22 //4. 循环遍历 for(e <- t1.productIterator){ println(e) } //5. 二元组称为对偶,可以作为键值对使用 val m1 = Map(("101",1),("102",2)) m1.foreach(a=>{//特殊变量方式 println(a._1+":"+a._2) }) m1.foreach(a=>println(a)) // m1.foreach(println(_)) } }