val 不可变 var可变
val myStr=“hello world!”
val myStr1:String=“hello world!”
val myStr2:java.lang.String=“hello world!”
import java.lang._ //java lang包里所有东西

Scala数据类型(都是类,scala.Int)
特殊:String java.lang.String
Byte Char Short Int Long Float Double Boolean

操作符
a 方法 b 等价于 a.方法(b)
例如:val sum1=5+3 val sum2=(5).+(3)

没有++ – 只能 a+=1

富包装类
scala.Int 有基本的计算方法,如+ - * /
某些方法不是基本的计算方法,如求两个数较大的那个,这些方法就在富包装类中实现
3 max 5 ===》 5

Range(for循环经常用到)可以支持不同数据类型的数值序列(Int Long Float Double Char BigInt BigDecimal)
例如:
1 to 5等价于1.to(5) (1,2,3,4,5)
1 until 5 (1,2,3,4)
1 to 10 by 2 (1,3,5,7,9)
0.5f to 5.9f by 0.8f (0.5,1.3,2.1,----)

控制台输入输出(import io.StdIn.
readInt readDouble readByte readShort readFloat readLong readChar readBoolean readLine
默认导入scala.Predef.

print()
println()
printf()支持c语言中的占位符%s

文件
写文件java.io.PrintWriter
val out=new PrintWriter(“output.txt”)
for (i<-1 to 5) out.println(i)
out.close()
读文件scala.io.Source
val inputFile=Source.fromFile(“output.txt”) //返回迭代器
val lines=inputFile.getLines
for (line <- lines) println(line)

异常处理Scala不支持java中的“受检查异常”(checked expection),将所有异常都当作“不受检查异常”(或成为运行时异常)
try{
val file=new FileReader(“input.txt”)
}catch{
case ex:FileNotFoundExpection=>
//process
case ex:IOException=>
//process
}finally{
file.close()
}

控制结构
if
while
for(变量<- 表达式) “变量<- 表达式”被称为生成器
for(i<-1 to 5) println(i)
守卫表达式
for(i<-1 to 5 if i%20) println(i)
多个生成器(双重循环)
for(i<- 1to 5;j <- 1 to 3) println(i*j)
多个生成器,每个生成器加守卫
for(i<- 1to 5 if i%2
0;j <- 1 to 3 if j!=i) println(i*j)
for推导式(将for循环产生的值用另一个变量保存起来,以便后续其他使用)
val r=for(i<- 1to 5 if i%2==0) yeild {println(i);i}//println(i)作用是打印,i作用是保存到r中
r=(2,4)

数据结构(容器Collection、列表List、集合Set、映射Map、迭代器Iterator、数组Array、元组Tuple)
有序容器、无序容器 可变容器、不可变容器
scala.collection
scala.collection.mutable可变容器
scala.collection.immutable不可变容器
scala基本语法速查手册
List 共享相同类型的不可变的有序对象序列(scala.collection.immutable)
var strList=List(“BigData”,“Hadoop”,“Spark”)
strList.head 返回"BigData"
strList.tail 返回除第一个元素以外剩下的元素列表List(“Hadoop”,“Spark”)
构建列表
val otherList=“Apache”::strList strList不发生变化,otherList为(“Apache”,“BigData”,“Hadoop”,“Spark”)
Scala定义了空列表对象Nil
val intList=1::2::3::Nil 与 val intList=List(1,2,3) 等价

Set 集合是不重复元素的无序容器(以hash方式存储,能快速找到对象)scala.collection.immutable,默认是创建不可变集合
var mySet=Set(“Hadoop”,“Spark”) 为什么不可变集合赋值给var???
mySet+=“Scala” 因为var val是指针,Set是对象;对象是不可变的,var指针可以变化
对比以下情况
import scala.collection.mutable.Set
val myMutableSet =Set(“Hadoop”,“Spark”)
myMutableSet+=“Scala”

映射(Map)是一系列键值对的容器,在映射中,键是唯一的,值不唯一
val unversity=Map(“S”->“School”,“T”->“Teacher”)
println(unversity(“S”))//不存在键S时,会抛出异常
val S=if (unversity.contains(“S”)) unversity(“S”) else 0
println(S)
导入可变映射 import scala.collection.mutable.Map
val unversity=Map(“S”->“School”,“T”->“Teacher”)
unversity(“S”)=“Student”
unversity+=(“SS”->“Student”,“MM”->“MM”)
循环遍历
for((k,v) <- unversity) printf("%s ,%s",k,v)
for(k<- unversity.keys) println(k)

迭代器(Iterator)不是集合,提供访问集合的一种方法. next和hasNext
val iter=Iterator(“A”,“B”,“C”)
while(iter.hasNext){
println(iter.next())
}
for(elem <- iter) println(elem)

Iterable有两种方法返回迭代器 grouped(返回元素的增量分块) 和sliding(返回滑动元素的窗口)
val xs=List(1,2,3,4,5)
val git=xs grouped 3 //按照3个元素一组进行划分,用git.next获取[(1,2,3),(4,5)]
val sit= xs sliding 3 //每个组为3个元素进行依次滑动[(1,2,3),(2,3,4),(3,4,5)]

数组(Array)可变、可索引、元素具有相同类型的数据集合
val intValueArr= new ArrayInt
intValueArr(0)=0
intValueArr(1)=1
intValueArr(2)=2
val intValueArr=Array(1,2,3)//与上面等价
多维数组
val myMatrix =Array.ofDimInt// 实际上是Array[Array[Int]]
myMatrix(0)(1)
Array属于定长数组 不定长数组scala.collection.mutable.ArrayBuffer
val aMutableArr=ArrayBuffer(10,20,30)
aMutableArr+=40
aMutableArr.insert(2,60,40)//从第二个元素后面插入60 40
aMutableArr-=40//把第一个元素为40的删掉
var temp=aMutableArr.remove(2)//把第二个元素删掉,并将元素值返回给temp

元组(不同类型的值的聚集)
val tuple=(“Bigdata”,“2015”,“45.0”)
println(tuple._1)

面向对象编程基础
类 对象 继承 特质 模式匹配
class Counter{
private var value=0
def increment():Unit={value+=1} //Unit表示不返回任何值
def increment():Unit=value+=1 //只有一行,可以去掉大括号,和上述等价
def increment() {value+=1} //:Unit=省略,只保留大括号,和上述等价
def current():Int={value}
}
val myCounter=new Counter 等价于 val myCounter=new Counter()、
myCounter.increment() 等价于 myCounter.increment
总结:scala在调用无参方法时,是可以省略方法后面的圆括号的

命令行中使用:load 文件名 可执行文件内容

java中是getter setter ,scala中将私有字段的修改改为一个方法
private var privateValue=0
def value=privateValue
def value_=(newValue:Int){
if (newValue>0) privateValue=newValue
}

构造器(一个主构造器和若干个辅构造器)
辅助构造器的名称为this,每个辅助构造器都必须调用一个此前已经定义的辅助构造器或者主构造器
class Counter{
private var name=""
def this(name:String){ //辅助构造器
this() //主构造器
this.name=name
}
}
scala每个类都有主构造器,默认是无参构造器,也可以将主构造器修改
class Counter(val name:String , val mode:Int){
}

当class 名字和object 名字完全一致时,两者构成伴生关系,当编译为java字节码时,class和object会被合二为一。class里面的成员为实例成员,方法变为实例方法;object里面的成员变为static成员,方法变为静态方法

继承
abstract class Car{ //是抽象类,不能直接被实例化
val carBrand:String //字段没有初始化值,就是一个抽象字段
def info() //抽象方法,不需要使用abstract关键字
def greeting(){println(“Welcome to my car!”)}
}

class BMWCar extends Car{
override val carBrand=“BMW” //重写超类字段,需要override关键字
def info(){printf(“This is a %s car.”,carBrand)}//重写超类的抽象方法时,不需要使用override,不过加上也可以
override def greeting() {println(“welcome to my BMW car”)}//重写超类的非抽象方法,必须使用override关键字
}

特质(java提供接口,scala没有接口,而提供了特质“trait”,不仅实现了接口的功能,还具备很多其他特性,可以同时拥有抽象方法和具体方法;一个类只能继承自一个超类,但可以实现多个特质“trait”,从而重用特质中的方法和字段,实现多重继承)
trait CarId{
var id:Int
def currentId():Int //定义了一个抽象方法
}

模式匹配:
val colorNum=3
val colorStr=colorNum match{
case 1=>“red”
case 2=>“green”
case unexpected=>unexpected+“is Not Allowed” //输出3 is Not Allowed
}
数据类型匹配
for(elem <- List(9,12.3,“Spark”,“Hadoop”,'Hello)){
val str=elem match{
case i:Int=>i+" is an int value"
case d:Double=>d+" is a double value"
case “Spark”:Int=>“Spark is found”
case s:String=>s+" is a String value"
case _=>“This is an unexpected value”
}
println(str)
}
case类是一种特殊的类,它们经过优化以被用于模式匹配(相当于enum)
case class Car(brand:String,price:Int)
val myBYDCar=new Car(“BYD”,89000)
val myBMWCar=new Car(“BMW”,189000)
val myBenzCar=new Car(“Benz”,1890000)
for (car <- List(myBYDCar,myBMWCar,myBenzCar)){
car match{
case Car(“BYD”,89000) => println(“Hello,BYD!”)
case Car(“BMW”,189000) => println(“Hello,BMW!”)
case Car(brand,price) => println(“Brand:”+brand+",Price:"+price+",do you want it?")
}
}

Option类型(返回值有时是空值,有时有值)

Option提供getOrElse,当没有返回值时,使用设置的值替换

foreach遇到None时,不会有任何操作

函数定义,函数式编程
val counter:Int => Int ={(value) => value+=1}
函数名 函数输入类型 =>函数输出类型 = 函数输入值=> 函数输出值

匿名函数
(num:Int)=>num2 也成为lambda表达式
(参数)=> 表达式 //如果参数只有一个,参数的圆括号可以省略
例子:
val myNumFunc:Int=>Int = (num:Int)=>num
2
println(myNumFunc(3))
当能推断出变量类型时,可以省略
val myNumFunc = (num:Int)=>num2
val myNumFunc:Int=>Int = (num)=>num
2
闭包是一个函数,比较特殊的函数
普通函数: val addMore=(x:Int)=>x>0
闭包: var more=1
val addMore=(x:Int)=>x+more
在定义函数中,使用外部变量,就是闭包(它反映了从开放到封闭的过程,每次都会重新生成闭包函数,因为引入的外部变量会变,例如上述的more值)

占位符(参数在函数字面量内仅出现一次)
val numList=List(-3,-4,1,2,3)
numList.filter(x=>x>0)
numList.filter(_>0)

针对集合的操作
for(elem <- List())
university.foreach(println)
dict.foreach(case(k,v)=>println(k+":"+v))
dict.foreach(kv=>println(kv.1+":"+kv.2))
books.map(s=>s.toUpperCase)
flatMap对每个输入返回一个集合,然后将生成的多个集合拍扁为一个集合
books flatmap (s=>s.toList)
university filter {kv=>kv.2 contains “school”}
university filter {kv=>kv.2 contains “school”}
list.reduceLeft(
+
) //从左到右规约
list.reduceRight(
+
) //从右到左规约
list.fold(10)(*)//初始值为10,然后继续规约

相关文章: