导读:
第一节:简介
1:六大特性
2:基础
Option
Nil
数组
列表
集合
元组
Map
函数
类和对象
特性
模式匹配
文件IO
scala语法:
http://note.youdao.com/noteshare?id=da59efd9487725f23c11c31ce0c81da8
第一节:简介(2.10)
1、六大特性
与java的无缝结合(本身基于jvm运行的),
类型推断(不需要定义类型),
适合分布式开发(内部的actor机制可以支持多线程的通信),
特性(类似java的接口,父类),
模式匹配(类似java的switch),
高阶函数(面向函数编程),
2、基础(scala语言包中有api的文档,api下index.html)
object //对象名
class //类名
def //方法名
var //变量 可以这样写:var a,b = (1,2) var a,b = 100
val //常量
数据类型
Byte |
8位有符号补码整数。数值区间为 -128 到 127 |
Short |
16位有符号补码整数。数值区间为 -32768 到 32767 |
Int |
32位有符号补码整数。数值区间为 -2147483648 到 2147483647 |
Long |
64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 |
Float |
32 位, IEEE 754标准的单精度浮点数 |
Double |
32 位 IEEE 754标准的单精度浮点数 |
Char |
16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF |
String |
字符序列 |
Boolean |
true或false |
Unit |
表示无返回值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。 |
Null |
null 或空引用(但不是空指针) |
Nothing |
Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型(当你不知道到底是什么类型,就可以定义为nothing)。 |
Any |
Any是所有其他类的超类(当你不知道到底是什么类型,就可以定义为any,定义成这个是比较合适的)。 |
AnyRef |
AnyRef类是Scala里所有引用类(reference class)的基类 string null option(选择) |
AnyVal |
AnyVal类是Scala里所有值类(value class)的基类 int double .. |
2.1 Option //引用类型,用来判断map是否空指针的
Some //option的一个子类
None //option的一个子类
例:
Option[T] ---两种返回---> some[T] none
2.2 Nil//长度为0的list,即空列表
例:
var list = Nil //定义了一个list,这个list是空的
2.3 for循环 range:范围 until:在...之前
for(i <- 1 to 100) //包头包尾,1 to 100实际是一个列表,var array = 1 to 100(Range类型)
for(i <- 1 until 100) //包头不包尾,1 until 100实际是一个列表,var array = 1 until 100(Range类型)
Range(1,100) //包头不包尾(这种方式几乎不用)
for(i <- 这里可以是任意集合)
2.4 printf //用来格式化一个字符串
var fs = printf("浮点型变量为 %f, 整型变量为 %d, 字符串为 %s", 3.1415, 2, str)
%.2f //精确小数点后2位
2.5 数组
一维数组
Array(“aaa”,111,1.2) //直接值放在里面的,类型可以混合
var a = New Array[String](3) //这种方式就要指定是什么类型,及数组的长度,添加方式是:a(0)=”uuu”
for(i <- a) //循环数组,a是数组名称
a.iterate.max //取数组中最大的
a.iterate.sum //取数组的和
... ...
多维数组
var myMatrix = ofDim[Int](3,3)
合并数组
concat()
例子:
var myList1 = Array(1.9, 2.9, 3.4, 3.5)
var myList2 = Array(8.9, 7.9, 0.4, 1.5)
var myList3 = concat( myList1, myList2)
.+: //添加一个数字的元素到数组
.++: //添加一个数组到数组
区间数组
range()
例子:
var myList2 = range(10,20) //这个数组里面是从10到19
2.6 列表
特点:
不可变(父类是immutable)
定义:
Var list1 = List(‘a’,2,3)
Var list2 = 100::(200::(300::Nil))
Var list3 = “a b”::(“c b”::(“t b”::Nil))
.+: //添加元素之后,赋值给新的列表,原列表不变
list2 = list.+:(400)
Var list3 = new ListBuffer[Int]() //这个是可变的list,父类是mutable
遍历:(高阶函数)
Foreach(无返回值)
List2.foreach(参数) //遍历list2,参数是函数
Map(有返回值)
List2.map{ _+1 } //list2的每个加1
List2.map{ i=>{i+1} }
// => 匿名函数
// i 形参,多个形参(i,j)
// {...}函数体,对传过来的参数进行操作
flatMap(同上)
List3.flatMap{ i=>{x.split(“ ”)} }
Map与flatMap的不同:
Map: { i=>{x.split(“ ”)} } split得到的是数组
操作之后的值还是作为一个整体到新列表或数组中,得到结果[a和b的数组,c和b的数组,t和b的数组]
flatMap: { i=>{x.split(“ ”)} }
操作之后的具体的值到新列表或数组中,得到结果[a,b,c,b,t,b]
列表的连接
// 使用 ::: 运算符
var fruit = site1 ::: site2
// 使用 List.:::() 方法
var fruit = site1.:::(site2)
// 使用 concat 方法
var fruit = List.concat(site1, site2)
List.fill()(创建一个指定重复数量的元素列表)
val site = List.fill(3)("Runoob") // 重复 Runoob 3次
val num = List.fill(10)(‘s’) // 重复元素 s, 10 次
List.reverse 用于将列表的顺序反转
val site = "Runoob" :: ("Google" :: ("Baidu" :: Nil))
site.reverse
2.7 集合
特点:
对象不重复
创建:
不可变(默认):
var set1 = Set(1,2) (引用的是scala.collection.immutable.Set)
可变:
var set1 = Set(1,2) (引用的是scala.collection.mutable.Set)
说明:
都可以进行添加、删除元素,
区别在于:不可变的是创建了一个新的集合,原集合不变,可变的是改变本身。
操作:
.head 返回集合第一个元素
.tail 返回一个集合,包含除了第一元素之外的其他元素
.isEmpty 在集合为空时返回true
.min 最小值
.max 最大值
.&或者.intersect 两个集合的交集
.&~ 两个集合的差集
连接(如果有重复元素会被自动移除):
++或set.++()
1 |
def +(elem: A): Set[A] 为集合添加新元素,x并创建一个新的集合,除非元素已存在 |
2 |
def -(elem: A): Set[A] 移除集合中的元素,并创建一个新的集合 |
3 |
def contains(elem: A): Boolean 如果元素在集合中存在,返回 true,否则返回 false。 |
4 |
def &(that: Set[A]): Set[A] 返回两个集合的交集 |
5 |
def &~(that: Set[A]): Set[A] 返回两个集合的差集 |
6 |
def +(elem1: A, elem2: A, elems: A*): Set[A] 通过添加传入指定集合的元素创建一个新的不可变集合 |
7 |
def ++(elems: A): Set[A] 合并两个集合 |
8 |
def -(elem1: A, elem2: A, elems: A*): Set[A] 通过移除传入指定集合的元素创建一个新的不可变集合 |
9 |
def addString(b: StringBuilder): StringBuilder 将不可变集合的所有元素添加到字符串缓冲区 |
10 |
def addString(b: StringBuilder, sep: String): StringBuilder 将不可变集合的所有元素添加到字符串缓冲区,并使用指定的分隔符 |
11 |
def apply(elem: A) 检测集合中是否包含指定元素 |
12 |
def count(p: (A) => Boolean): Int 计算满足指定条件的集合元素个数 |
13 |
def copyToArray(xs: Array[A], start: Int, len: Int): Unit 复制不可变集合元素到数组 |
14 |
def diff(that: Set[A]): Set[A] 比较两个集合的差集 |
15 |
def drop(n: Int): Set[A]] 返回丢弃前n个元素新集合 |
16 |
def dropRight(n: Int): Set[A] 返回丢弃最后n个元素新集合 |
17 |
def dropWhile(p: (A) => Boolean): Set[A] 从左向右丢弃元素,直到条件p不成立 |
18 |
def equals(that: Any): Boolean equals 方法可用于任意序列。用于比较系列是否相等。 |
19 |
def exists(p: (A) => Boolean): Boolean 判断不可变集合中指定条件的元素是否存在。 |
20 |
def filter(p: (A) => Boolean): Set[A] 输出符合指定条件的所有不可变集合元素。 |
21 |
def find(p: (A) => Boolean): Option[A] 查找不可变集合中满足指定条件的第一个元素 |
22 |
def forall(p: (A) => Boolean): Boolean 查找不可变集合中满足指定条件的所有元素 |
23 |
def foreach(f: (A) => Unit): Unit 将函数应用到不可变集合的所有元素 |
24 |
def head: A 获取不可变集合的第一个元素 |
25 |
def init: Set[A] 返回所有元素,除了最后一个 |
26 |
def intersect(that: Set[A]): Set[A] 计算两个集合的交集 |
27 |
def isEmpty: Boolean 判断集合是否为空 |
28 |
def iterator: Iterator[A] 创建一个新的迭代器来迭代元素 |
29 |
def last: A 返回最后一个元素 |
30 |
def map[B](f: (A) => B): immutable.Set[B] 通过给定的方法将所有元素重新计算 |
31 |
def max: A 查找最大元素 |
32 |
def min: A 查找最小元素 |
33 |
def mkString: String 集合所有元素作为字符串显示 |
34 |
def mkString(sep: String): String 使用分隔符将集合所有元素作为字符串显示 |
35 |
def product: A 返回不可变集合中数字元素的积。 |
36 |
def size: Int 返回不可变集合元素的数量 |
37 |
def splitAt(n: Int): (Set[A], Set[A]) 把不可变集合拆分为两个容器,第一个由前 n 个元素组成,第二个由剩下的元素组成 |
38 |
def subsetOf(that: Set[A]): Boolean 如果集合中含有子集返回 true,否则返回false |
39 |
def sum: A 返回不可变集合中所有数字元素之和 |
40 |
def tail: Set[A] 返回一个不可变集合中除了第一元素之外的其他元素 |
41 |
def take(n: Int): Set[A] 返回前 n 个元素 |
42 |
def takeRight(n: Int):Set[A] 返回后 n 个元素 |
43 |
def toArray: Array[A] 将集合转换为数组 |
44 |
def toBuffer[B >: A]: Buffer[B] 返回缓冲区,包含了不可变集合的所有元素 |
45 |
def toList: List[A] 返回 List,包含了不可变集合的所有元素 |
46 |
def toMap[T, U]: Map[T, U] 返回 Map,包含了不可变集合的所有元素 |
47 |
def toSeq: Seq[A] 返回 Seq,包含了不可变集合的所有元素 |
48 |
def toString(): String 返回一个字符串,以对象来表示 |
2.8 元组(用的最多的二元组)
特点:
不可变,可以包含不同类型的元素
定义:
var t = (1,2,3) //这个就是长度是3的元组
var t = New Tuple3(1,2,3) //这个就是长度是3的元组
Tuple3 //这个3是代表长度是3的,目前支持最大到22
t._1 //获取元组的第一个值(底标是以1开始的)
操作:
Tuple.productIterator() //迭代元组(获取所有元素):
Tuple.toString() //转字符串
Tuple.swap //交换元组中两个元素的位置,所以只会有2个元素的元组可用
2.9 map
创建:
不可变(import scala.collection.immutable.Map):
val A = Map("red" -> "#FF0000", "azure" -> "#F0FFFF")
可变(import scala.collection.mutable.Map):
操作:
Keys //返回 Map 所有的键(key),返回的是set集合。
Values //返回 Map 所有的值(value),返回的是MapLike
isEmpty //是否为空
+= //添加kv对,A += ('I' -> 1)
++或者.++() //合并两个map,相同的key会覆盖
Keys //取key值
例(循环A的key value):
A.keys.foreach{i =>
print( "Key = " + i )
println(" Value = " + A(i) )
}
Contains //是否包含某个key
例:
A.contains(‘sss’)
1 |
def ++(xs: Map[(A, B)]): Map[A, B] 返回一个新的 Map,新的 Map xs 组成 |
2 |
def -(elem1: A, elem2: A, elems: A*): Map[A, B] 返回一个新的 Map, 移除 key 为 elem1, elem2 或其他 elems。 |
3 |
def --(xs: GTO[A]): Map[A, B] 返回一个新的 Map, 移除 xs 对象中对应的 key |
4 |
def get(key: A): Option[B] 返回指定 key 的值 |
5 |
def iterator: Iterator[(A, B)] 创建新的迭代器,并输出 key/value 对 |
6 |
def addString(b: StringBuilder): StringBuilder 将 Map 中的所有元素附加到StringBuilder,可加入分隔符 |
7 |
def addString(b: StringBuilder, sep: String): StringBuilder 将 Map 中的所有元素附加到StringBuilder,可加入分隔符 |
8 |
def apply(key: A): B 返回指定键的值,如果不存在返回 Map 的默认方法 |
9 |
def clear(): Unit 清空 Map |
10 |
def clone(): Map[A, B] 从一个 Map 复制到另一个 Map |
11 |
def contains(key: A): Boolean 如果 Map 中存在指定 key,返回 true,否则返回 false。 |
12 |
def copyToArray(xs: Array[(A, B)]): Unit 复制集合到数组 |
13 |
def count(p: ((A, B)) => Boolean): Int 计算满足指定条件的集合元素数量 |
14 |
def default(key: A): B 定义 Map 的默认值,在 key 不存在时返回。 |
15 |
def drop(n: Int): Map[A, B] 返回丢弃前n个元素新集合 |
16 |
def dropRight(n: Int): Map[A, B] 返回丢弃最后n个元素新集合 |
17 |
def dropWhile(p: ((A, B)) => Boolean): Map[A, B] 从左向右丢弃元素,直到条件p不成立 |
18 |
def empty: Map[A, B] 返回相同类型的空 Map |
19 |
def equals(that: Any): Boolean 如果两个 Map 相等(key/value 均相等),返回true,否则返回false |
20 |
def exists(p: ((A, B)) => Boolean): Boolean 判断集合中指定条件的元素是否存在 |
21 |
def filter(p: ((A, B))=> Boolean): Map[A, B] 返回满足指定条件的所有集合 |
22 |
def filterKeys(p: (A) => Boolean): Map[A, B] 返回符合指定条件的不可变 Map |
23 |
def find(p: ((A, B)) => Boolean): Option[(A, B)] 查找集合中满足指定条件的第一个元素 |
24 |
def foreach(f: ((A, B)) => Unit): Unit 将函数应用到集合的所有元素 |
25 |
def init: Map[A, B] 返回所有元素,除了最后一个 |
26 |
def isEmpty: Boolean 检测 Map 是否为空 |
27 |
def keys: Iterable[A] 返回所有的key/p> |
28 |
def last: (A, B) 返回最后一个元素 |
29 |
def max: (A, B) 查找最大元素 |
30 |
def min: (A, B) 查找最小元素 |
31 |
def mkString: String 集合所有元素作为字符串显示 |
32 |
def product: (A, B) 返回集合中数字元素的积。 |
33 |
def remove(key: A): Option[B] 移除指定 key |
34 |
def retain(p: (A, B) => Boolean): Map.this.type 如果符合满足条件的返回 true |
35 |
def size: Int 返回 Map 元素的个数 |
36 |
def sum: (A, B) 返回集合中所有数字元素之和 |
37 |
def tail: Map[A, B] 返回一个集合中除了第一元素之外的其他元素 |
38 |
def take(n: Int): Map[A, B] 返回前 n 个元素 |
39 |
def takeRight(n: Int): Map[A, B] 返回后 n 个元素 |
40 |
def takeWhile(p: ((A, B)) => Boolean): Map[A, B] 返回满足指定条件的元素 |
41 |
def toArray: Array[(A, B)] 集合转数组 |
42 |
def toBuffer[B >: A]: Buffer[B] 返回缓冲区,包含了 Map 的所有元素 |
43 |
def toList: List[A] 返回 List,包含了 Map 的所有元素 |
44 |
def toSeq: Seq[A] 返回 Seq,包含了 Map 的所有元素 |
45 |
def toSet: Set[A] 返回 Set,包含了 Map 的所有元素 |
46 |
def toString(): String 返回字符串对象 |
2.10 option
返回值:
some[T]或none
用法(一般用在map.get):
var opt = Map.get(“key1”) //获取Map的key1的值,
//opt就是option[T]类型,
//T到底是什么类型,取决于key1的value值的类型
//如果有值返回some[T],没有值返回none
//可以Map.getOrElse,取值更方便,防止出错
操作:
opt.get //获取值
opt.getOrElse(“A”,”B”) //如果没有获取到key是A值,则返回这个默认值B
1 |
def get: A 获取可选值 |
2 |
def isEmpty: Boolean 检测可选类型值是否为 None,是的话返回 true,否则返回 false |
3 |
def productArity: Int 返回元素个数, A(x_1, ..., x_k), 返回 k |
4 |
def productElement(n: Int): Any 获取指定的可选项,以 0 为起始。即 A(x_1, ..., x_k), 返回 x_(n+1) , 0 < n < k. |
5 |
def exists(p: (A) => Boolean): Boolean 如果可选项中指定条件的元素存在且不为 None 返回 true,否则返回 false。 |
6 |
def filter(p: (A) => Boolean): Option[A] 如果选项包含有值,而且传递给 filter 的条件函数返回 true, filter 会返回 Some 实例。 否则,返回值为 None 。 |
7 |
def filterNot(p: (A) => Boolean): Option[A] 如果选项包含有值,而且传递给 filter 的条件函数返回 false, filter 会返回 Some 实例。 否则,返回值为 None 。 |
8 |
def flatMap[B](f: (A) => Option[B]): Option[B] 如果选项包含有值,则传递给函数 f 处理后返回,否则返回 None |
9 |
def foreach[U](f: (A) => U): Unit 如果选项包含有值,则将每个值传递给函数 f, 否则不处理。 |
10 |
def getOrElse[B >: A](default: => B): B 如果选项包含有值,返回选项值,否则返回设定的默认值。 |
11 |
def isDefined: Boolean 如果可选值是 Some 的实例返回 true,否则返回 false。 |
12 |
def iterator: Iterator[A] 如果选项包含有值,迭代出可选值。如果可选值为空则返回空迭代器。 |
13 |
def map[B](f: (A) => B): Option[B] 如果选项包含有值, 返回由函数 f 处理后的 Some,否则返回 None |
14 |
def orElse[B >: A](alternative: => Option[B]): Option[B] 如果一个 Option 是 None , orElse 方法会返回传名参数的值,否则,就直接返回这个 Option。 |
15 |
def orNull 如果选项包含有值返回选项值,否则返回 null。 |
2.11 函数
定义:
def test(x:Int): Unit= {
X; //最后一行如果执行之后有结果,则作为返回值自动返回(如果声明了Unit则不会返回)
}
def test(x:Int)={ //一般不写返回值类型,这样会自动判断是否返回及返回什么(通常写法)
X;
}
def test(x:Int){ //如果没有=,就没有返回值
X;
}
内嵌函数:
定义在函数中的函数
可变参数函数:
//x,y至少要传2个参数
//z是可变参数(数量可变),z是一个int的列表
def test(x:Int,y:Int,z:Int*)={
For(i <- z){}
}
默认参数函数:
//y是固定的参数
//默认参数不能和可变参数一起使用
def test(x:Int,y:Int=1)={
}
匿名函数:
(x:Int,y:Int)=>{
x+y
}
例:
var a = (x:Int,y:Int)=>{}
这样就可以被调用 a(100,200)
偏应用函数:
就是对某个函数的再次封装,固定不变的参数写死,根据具体的业务去设置可变的参数。
例:
def test(x:Date,y:String)={} //这是一个普通函数
var date = new Date()
var f2 = test(date,_:String) //f2就是偏应用函数,_是代表不知道要输入什么(类似占位符)
f2(“hello”) //调用f2
递归函数:
自己调自己
高阶函数(多次的迭代处理,流式处理等):和spark的行动算子与转换算子有联系
函数的参数是函数;
//y:Int=>String 声明要传入的函数的类型,
y可认为是代表一个函数的名
Int是要传入的函数的参数类型,如果是多个参数y:(Int,String)=>String
String是要传入参数的返回值类型
def test(x:Int,y:Int=>Int)={}
调用:
test(10,test5) //test5就是要传入的函数,只要个函数名字就行了,在高阶函数中已经定义好了
函数的返回值是函数;
//(Int,Int)=>Int 要返回的函数有两个Int参数且返回值是个Int
def test():(Int,Int)=>Int={
//第一种返回方式:匿名函数
return (x:Int,y:Int)=>{x+y}
//第二种返回方式:内嵌函数
def test1(x:Int,y:Int)={x+y}
}
调用:
test()(100,200)
2.12 类和对象
class与object,可以写在一个文件里面
例:
//创建实例时候,除了定义的函数不执行,其他的都执行
class Dog(xname:String,xage:Int){ //()里面的name和age是形参,形参写在这简化初始化函数
var name = xname; //默认的是public,private var name = xname :设置成了私有的
var age = xage;
def test(){}
}
object Test1{ //静态单例的对象,里面的方法可以直接调用
def test2(){
//创建class实例
var d = new Dog(“11”,1)
d.test()
}
}
注意:
一个里面的class与object名字可以相同,这时候两个互为伴生对象,伴生类,相互之间可以访问相互的私有属性
继承:
定义一个抽象的父类(也可以定义一个普通的类):
abstract class Dog(xname:String){
var name = xname
def test()={} //普通函数
def test1() //抽象函数
}
class Dog11(xname:String) extends Dog(xname) { //单继承
override def test()={ //重写普通函数
}
def test1()={ //重写抽象函数
}
def test2()={ //自己的函数
}
}
2.13 trait特性(相当于java接口与抽象类的合体)
定义:
trait test1{ //不能有参数
}
trait test2{ //不能有参数
}
class test extends test1 with test2{ //多实现(extends with )
}
比较器:
内部比较器:
Java: 实现Comparable接口,具体方法compare(name,age)
Scala: 继承Ordered父类,实现Comparable接口,具体方法compare(name,age)
外部比较器:
Java: 实现Comparator接口,具体方法compareTo(persion1,persion2)
Scala: 继承Ordering父类,实现Comparator接口,具体方法compareTo(persion1,persion2)
例子:
class secondarySort(val first : String,val second: Int) extends Ordered[secondarySort] with Serializable{
def compare(that:secondarySort)={ //比较对象内部
if(this.first == that.first){
this.second - that.second
}else{
this.first.compareTo(that.first) //对两个name按照asc码比较,按照字典序
}
}
}
2.14 模式匹配
定义:
def test(x:Any){
x match{
case “111” => “匹配到是111”
case x:Int => “匹配到是Int类型”
case _ => “没有匹配到”
}
}
def test(x:Any) = x match{
case “111” => “匹配到是111”
case x:Int => “匹配到是Int类型”
case _ => “没有匹配到”
}
2.15 文件IO
读取文件:
Source.fromFile() //这个是读文件
Source.from... //可以读取很多东西