我平时主要是写 Java,有时候读源码如 Kafka 或者 Spark 会遇见 Scala 的语法,总觉得有点别扭。我总结了一下 Scala 和 Java 有差异的语法。目的就是快速入门,消除别扭
和 var
- Scala 有两类变量:val 和 var
- val 类似 Java 的 final 变量,一旦初始化就不能被重新赋值
- var 可以被重新赋值
object Test {
def main(args: Array[String]) {
// 申明变量的关键字 var val
var v1: String = "code"
// 类型可以自动推断
var v2 = 2
// :类型,手动指定类型
val v3: Double = 3.14
// val 相当于常量,不能不能改变其引用的对象本身
val v4 = 3
// 但是可以改变其引用的对象的其他属性
val v5 = Array(1, 2, 3)
v5(1) = 10
}
}
2.集合
List
List 的创建有两种方式
object Test {
def main(args: Array[String]) {
// 定义列表有两种写法 :: 和 List
//定义 列表
val empty = Nil
// ::构造列表
val nums = 1 :: (2 :: (3 :: (4 :: Nil)))
//定义 List
val x = List(1, 2, 3, 4)
}
}
元组
元祖就是一堆数据的不可变集合,通过 _下标 访问
object Test {
def main(args: Array[String]) {
val z1 = (10, "Runoob", 3.14, true)
println(z1._3)
}
}
3.循环
Scala 的 while 和 Java 一样,但是 for 循环差异很大
object Test {
def main(args: Array[String]) {
// for 循环不支持 continue 和 break
// to 前闭后闭
for (i <- 1 to 3) println(i)
// reverse 倒序
for (i <- (1 to 3).reverse) println(i)
// 前闭后开
for (i <- 1 until 3) println(i)
//循环守卫 if 控制输出
for (i <- 1 to 10 if i % 3 == 0) println(i)
//循环守卫 if 控制输出
for (i <- 1 to 3; j = 4 - i) println(j)
// 双重 for 循环
for (i <- 1 to 3; j <- 1 to 3) println(s"i=$i, j=$j, i+j=${i + j}")
// 返回一个集合
val x = for (i <- 1 to 10) yield i
}
}
4.函数
Scala 的函数,写法如下
def max(x: Int, y: Int): Int = {
if (x > y) x
else y
}
可以做为一个对象赋值给一个变量
object Test {
def main(args: Array[String]) {
def sayHello(name: String): String = {
"Hello," + name
}
//Scala中的函数是一等公民,可以直接将函数作为值赋值给变量
//将函数赋值给变量时,必须在函数后面加上“ _”或“(_)”
val hi = sayHello _
println(hi("Ada"))
//也可以使用匿名函数
val hello = (name: String) => println("hello," + name)
hello("MilkTea")
}
}
object 就是常说的伴生对象,伴生对象是这个类的单例,它的方法就是这个类的静态方法
class Account {
val id = Account.newUniqueNumber()
private var balance = 0.0
}
object Account {
private var lastNumber = 0
private def newUniqueNumber() = {
lastNumber += 1
lastNumber
}
}
trait 相当于 Java 中的接口,但可以定义抽象方法,也可以定义字段和方法的实现
trait HasLegs {
//抽象字段
val legs: Int
// 定义一个具体的方法
def walk() {
println("Use" + legs + "legs to walk")
}
// 定义一个抽象方法
def fly()
}
class
样例类关键字 case 类
case class Person (age: Int, name: String)
它非常的强大:
- 伴生对象:编译会产生两个class, 和Person$class. 编译器自动添加了一个伴 生对象object Person
- apply()方法:伴生对象Person里面默认实现了创建对象的apply()方法,创建实例的时候不需要使用关键字 new,可以直接通过Person(age, name)得到一个实例对象
- 字段默认加上了val:age和name都被定义成了val(final),也可修改为 var
- case 类自动地为所有类字段定义 Getter 方法
- toString()、hashCode()和equals() 使用age和name构建
- 实现Serializable接口
8.模式匹配
等效于 switch
模式匹配类似于 Java switch
val m = 3
m match {
case 1 => println("one")
case 2 => println("two")
case _ => println("many")
}
匹配不同类型
但是模式匹配又比 switch 功能更多,如可以匹配不同类型
object Test {
def main(args: Array[String]) {
println(matchTest2(1))
println(matchTest2(6))
println(matchTest2("two"))
println(matchTest2("7"))
}
def matchTest(x: Any): Any = x match {
case 1 => "one" //匹配值
case "two" => 2 //另一种类型的匹配值
case y: Int => "" //类型匹配,相当于 instanceof
case _ => "many" // 默认
}
}
配合 Option
Option 表达一种对结果的不确定,有可能有值,有可能为空,经常和模式匹配勾搭在一起
object Test {
def main(args: Array[String]) {
val keywords = Map("scala" -> "option", "java" -> "optional")
// 能不能获取
println(display(keywords.get("java")))
println(display(keywords.get("c")))
}
def display(game: Option[String]) = game match {
case Some(s) => s
case None => "unkown"
}
}
- Option 的目的是为了避免使用null,
- Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None
9.高阶函数
高阶函数:接收函数作为参数的函数,或返回值为函数的函数,被称作高阶函数
object Test {
def main(args: Array[String]) {
def higherOrderHi(func: (String) => Unit, name: String): Unit = {
func(name)
}
higherOrderHi(hello, "Higher")
}
}
常用高阶函数
object Test {
def main(args: Array[String]) {
// map: 对传入的每个元素都进行映射,返回一个处理后的元素
Array(1, 2, 3, 4, 5).map(_ * 10)
//foreach: 对传入的每个元素都进行处理,但是没有返回值
Array(1, 2, 3, 4, 5).map(_ * 10).foreach(println _)
//filter: 对传入的每个元素都进行条件判断,如果对元素返回true,则保留该元素,否则过滤掉该元素
(1 to 50).filter(_ % 10 == 0)
//reduceLeft: 从左侧元素开始,进行reduce操作,即先对元素1和元素2进行处理,然 后将结果与元素3处理,再将结果与元素4处理,依次类推,即为reduce
(1 to 4).reduceLeft( _ * _)
}
}
10.闭包
闭包由代码和代码用到的任何非局部变量定义而成
object Test {
def main(args: Array[String]) {
def mulBy(factor: Double) = (x: Double) => factor * x
// mulBy 和 3 构成一个闭包
val triple = mulBy(3)
val half = mulBy(0.5)
println(s"${triple(14)} ${half(14)}")
}
}