初识scala
使用scala解释器
scala> 1+2
res0: Int = 3
scala> res0 * 3
res1: Int = 9
scala>
res0 变量名
Int 变量类型
- Scala包概念类似Java
- Java所有基本类型在Scala中都有对应的类
scala> println("hello world")
定义变量
scala两种变量,val和var:
- val: 类似java final变量
- var: 类似java non-final变量
scala> val msg = "hahaha!"
msg: String = hahaha!
scala>
- scala的字符串是有java的String类实现
- scala可以不显示指定变量类型,解释器可以动态推断
定义函数
scala> def max(x:Int, y:Int):Int = {
| if (x > y) x
| else y
| }
max: (x: Int, y: Int)Int
scala>
- 函数参数列表中必须要指定类型信息
- 返回类型可以不写,编译器可以自动推断
- 有些情况下必须要指定返回类型,如:递归函数
无返回参数:
scala> def max(x:Int, y:Int) = {
| if (x > y) x
| else y
| }
max: (x: Int, y: Int)Int
scala>
无参:
scala> def greet() = println("Hello World")
greet: ()Unit
scala>
- 无返回值时对应Unit类型
- Scala Unit类型对应Java的void
Scala脚本
创建example.scala,写入:
println("hello world!!!")
执行脚本
$ scala example.scala
hello world!!!
- Scala语句放在Scala文件中, 顺序执行
传入参数
//Say hello
/**
* Say hello
*/
println("hello " + args(0))
$ scala example.scala cat
hello cat
- 参数是从下标0开始获取,而不是1, args(0)
- 字符串连接可用 ‘+’
- 注释://、/* */
while循环和if
var i = 0
while (i < args.length) {
println(args(i))
i += 1
}
$ scala printarg.scala 1 2 3
1
2
3
- scala不支持i++操作
var i = 0
while (i < args.length) {
if (i > 0) {
println(args(i))
}
i += 1
}
$ scala printarg.scala 1 2 3
2
3
foreach和for循环
支持function style
args.foreach(arg => println(arg))
$ scala printarg.scala 1 2 3
1
2
3
显示指定参数类型
args.foreach((arg : String) => println(arg))
更简洁写法:单行一个参数
args.foreach(println)
for
for (arg <- args)
println(arg)
- arg是val类型,不能在循环体中赋值
- 每次循环都是重新创建一个arg变量
初始化数组
val greetings = new Array[String](3)
greetings(0) = "hello"
greetings(1) = ","
greetings(2) = "world!"
greetings.foreach(print)
println
指定数组类型
val greetings : Array[String] = new Array[String](3)
- greetings是不可变的
- greetings中的对象可以改变
数组元素访问
val greetings = new Array[String](3)
greetings(0) = "hello"
greetings(1) = ","
greetings(2) = "world!"
for (i <- 0 to 2)
print(greetings(i))
- scala没有操作符概念
- 0 to 2 => (0).to(2), 调用对象0的to函数
- 1 + 2 => (1).+(2), 调用对象1的+函数
- greetings(i) => greetings.apply(i)
- greetings(0) = 1 => greetings.update(0, 1)
等价代码
val greetStrings = new Array[String](3)
greetStrings.update(0, "Hello")
greetStrings.update(1, ", ")
greetStrings.update(2, "world!\n")
for (i <- 0.to(2))
print(greetStrings.apply(i))
- scala一切都是对象,包括:数组、表达式、函数
- 统一不会造成性能消耗,scala编译器内部使用java的array、基本类型
val numberNames = Array("zero", "one", "two")
- 可转换为静态方法调用:Array.apply(“zero”, “one”, “two”)
使用List
scala> val oneTwo = List(1, 2)
oneTwo: List[Int] = List(1, 2)
scala> val threeFour = List(3, 4)
threeFour: List[Int] = List(3, 4)
scala> oneTwo ::: threeFour
res0: List[Int] = List(1, 2, 3, 4)
scala>
- List不可变
- 只能包含同一类型元素
- ::: 表示List连接
scala> val oneTwo = List(1, 2)
oneTwo: List[Int] = List(1, 2)
scala> 0 :: oneTwo
res1: List[Int] = List(0, 1, 2)
scala>
- :: 从list头部追加新元素,并返回新list
- 以冒号结尾的方法,是由右边的操作数调用
- Nil 空List
scala> val oneTwoThree = 1 :: 2 :: 3 :: Nil
oneTwoThree: List[Int] = List(1, 2, 3)
函数 | 作用 |
---|---|
List(), Nil | 空List |
List(“1”, “2”, “3”) | 创建新列表 |
val thrill = “Will” :: “fill” :: “until” :: Nil | 创建列表,包含元素:Will,fill,until |
List(“a”,”b”) ::: List(“c”, “d”, “e”) | 连接两个列表 |
thrill(2) | 访问第3个元素 |
thrill.count(s => s.length == 4) | 返回长度是4的元素个数 |
thrill.drop(2) | 返回除去前2个元素的列表 |
thrill.dropRight(2) | 返回除去最后2个元素的列表 |
thrill.exists(s => s == “until”) | 返回列表元素是否存在until |
thrill.filter(s => s.length == 4) | 过滤出长度为4的列表元素 |
thrill.forall(s => s.endsWith(“l”)) | 是否所有元素以“l”结尾 |
thrill.foreach(s => print(s)) | 打印所有列表元素 |
thrill.foreach(print) | 打印所有列表元素 |
thrill.head | 返回列表第一个元素 |
thrill.init | 返回列表除去最后一个元素的所有元素 |
thrill.isEmplty | 列表是否为空 |
thrill.last | 返回列表最后一个元素 |
thrill.length | 返回列表长度 |
thill.map(s => s + ‘y’) | 列表所有元素结尾添加后缀‘y’ |
thrill.mkString(“,”) | 列表元素连接成字符串,以“,”分割 |
thirll.filterNot(s => s.length == 4) | 过滤掉长度为4的元素 |
thrill.reverse | 翻转列表 |
thrill.sort((s, t) => s.charAt(0).toLower < t.charAt(0).toLower) | 返回以首字符排序后的列表 |
thrill.tail | 返回出去首元素后的剩余元素列表 |
使用tuple
- tuple不可变
- 可以包含不同类型元素
scala> val pair = (100, "hight score")
pair: (Int, String) = (100,hight score)
scala> pair._1
res15: Int = 100
scala> pair._2
res16: String = hight score
scala>
使用set和map
Set
scala> var jetSet = Set("a", "b")
jetSet: scala.collection.immutable.Set[String] = Set(a, b)
scala> jetSet += "c"
scala> println(jetSet)
Set(a, b, c)
scala>
scala> import scala.collection.mutable
import scala.collection.mutable
scala> val jetSet = mutable.Set("a", "b")
jetSet: scala.collection.mutable.Set[String] = Set(a, b)
scala> jetSet += "c"
res31: jetSet.type = Set(c, a, b)
scala>
- Set分为immutable set和mutable Set
- immutable Set没有实现+=函数,mutable Set实现了+=函数
- immutable Set使用+=操作时不能定义为val变量
map
- Map也分为immutable和mutable
scala> val relationMap = mutable.Map[Int, String]()
relationMap: scala.collection.mutable.Map[Int,String] = Map()
scala> relationMap += (1 -> "brother")
res32: relationMap.type = Map(1 -> brother)
scala> relationMap += (2 -> "sister")
res33: relationMap.type = Map(2 -> sister, 1 -> brother)
scala> println(relationMap)
Map(2 -> sister, 1 -> brother)
scala> println(relationMap(2))
sister
scala>
scala> val numberMap = Map(1-> "one", 2 -> "two", 3 -> "three", 4 -> "four")
numberMap: scala.collection.immutable.Map[Int,String] = Map(1 -> one, 2 -> two, 3 -> three, 4 -> four)
scala>
- x -> y 返回tuple (x, y)
- map调用 += 函数保存tuple
识别function style
imperative style
def printArgs(args : Array[String]) : Unit {
var i = 0
while (i < args.length) {
println(args[i])
i += 1
}
}
function style
def printArgs(args : Array[String]) : Unit {
for (arg <- args) {
println(arg)
}
}
def printArgs(args : Array[String]) : Unit {
args.foreach(print)
}
- 尽可能少定义var变量
- 首先使用val,immutable对象、方法,除非有必要,则使用var,mutable对象、方法
读文件
import scala.io.Source
if (args.length > 0) {
for (line <- Source.fromFile(args(0)).getLines()) {
println(line)
}
}
- Source.fromFile(args(0)) 返回Source对象
- Source对象.getLines()返回Iterator对象,每次迭代返回一行