首先很高兴能成为王老师3000门徒之一,在新年第一天第一课《Scala光速入门》就长达三个小时,在这三个小时的时间里面,整体上感觉难度不是很大,但由于前期没有准备Scala环境,仅仅听导致效率很低,导致中间大半个小时基本上收获比较低,今天上午我把Scala环境搭建完毕,也把spark源码下载下来,后面紧跟着王老师的脚步,提高上课效率,课后及时复习;
第一课主要讲的内容总结如下:
1,scale基于JVM,scale可以调用java所有方法和接口
2,scale是完全面向对象(一切皆对象,一切对象都有方法),
3,scale实现代码量是java的五分之一或者十分之一;
4,王老师推荐使用Scale 2.10.4版本;
5,Val 至关重要,不希望数据改变,就是用val,初步达到目标
scala> val rsult = 2+10
rsult: Int = 12
scala> rsult = 13
<console>:12: error: reassignment to val
rsult = 13
^
6,Scala支持的基本数据类型,如果你是个Java程序员,你会发现Java支持的基本数据类型,Scala都有对应的支持,不过Scala的数据类型都是对象(比如整数),这些基本类型都可以通过隐式自动转换的形式支持比Java基本数据类型更多的方法
scala> 1+2
res13: Int = 3
scala> 1.5+2
res14: Double = 3.5
7,TAB快捷键的作用,输入一部分内容,按Tab键可以快捷查询
scala> res14.is
isInfinite isNaN isValidByte isValidShort
isInfinity isNegInfinity isValidChar isWhole
isInstanceOf isPosInfinity isValidInt
8,_用法
1 import导入包的所有成员,相当于java的*,而*在scala中可以作为合法的identifier。比java方便的一点是它可以导入某个类下的所有静态成员,java则需要import static。
2 占位符:这个用法比较多,表示某一个参数。比如对collection或sequence调用方法map、filter、sortWith、foreach等等表示对每一个元素进行处理,甚至可以使用 http://_.XXX方式;还有参数推导时f(250*_),假设已知f的参数类型是Int=>Int的函数类型时,可以在匿名函数中250*_使用_表示Int 参数,还比如val f = 250 * (_: Int);在模式匹配中根据unapply来初始化变量或集合时,如果不关心变量的某个具体属性或集合的某些元素则使用_来忽略,比如val Array(first, second, _*) = arr,只将arr的前2个值分别赋给first和second,这在match case class中用得比较多。
3 对变量进行默认初始化,比如var i:Int=_
4 访问tuple变量的某个元素时通过索引_n来取得第n个元素
5 向函数或方法传入可变参数时不能直接传入Range或集合或数组对象,需要使用:_*转换才可传入
6 类的setter方法,比如类A中定义了var f,则相当于定义了setter方法f_=,当然你可以自己定义f_=方法来完成更多的事情,比如设置前作一些判断或预处理之类的操作
7 用于将方法转换成函数,比如val f=sqrt _,以后直接调用f(250)就能求平方根了
scala> min(20,4) <console>:12: error: not found: value min min(20,4) ^
scala> import scala.math._
import scala.math._
scala> min(20,4)
res16: Int = 4
9,数组,访问使用(),而不像Java中的[]
scala> Array(1,2,3,4)
res17: Array[Int] = Array(1, 2, 3, 4)
scala> val array = Array(1,2,3,4)
array: Array[Int] = Array(1, 2, 3, 4)
scala> array
res18: Array[Int] = Array(1, 2, 3, 4)
scala> Array(1,2,3,4)
res17: Array[Int] = Array(1, 2, 3, 4)
scala> val array = Array(1,2,3,4)
array: Array[Int] = Array(1, 2, 3, 4)
scala> array
res18: Array[Int] = Array(1, 2, 3, 4)
scala> res18.apply(0)
res19: Int = 1
scala> res18.apply(0,1,2)
<console>:17: error: too many arguments for method apply: (i: Int)Int in cla
rray
res18.apply(0,1,2)
^
scala> var array = Array.apply(0,1,2)
array: Array[Int] = Array(0, 1, 2)
scala> val arr = new Array[Int](5)
arr: Array[Int] = Array(0, 0, 0, 0, 0)
scala> arr(3)
res21: Int = 0
scala> arr(2)=8
scala> arr
res23: Array[Int] = Array(0, 0, 8, 0, 0)
scala> arr.apply(2)
res24: Int = 8
scala> val arrBuffer = ArrayBuffer[int]()
<console>:14: error: not found: value ArrayBuffer
val arrBuffer = ArrayBuffer[int]()
^
<console>:14: error: not found: type int
val arrBuffer = ArrayBuffer[int]()
^
scala> import scala.collection.mutable.Array
ArrayBuffer ArrayLike ArraySeq
ArrayBuilder ArrayOps ArrayStack
scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer
scala> val arrBuffer = ArrayBuffer[Int]()
arrBuffer: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
scala> arrBuffer +=(11,1,3,4,5)
res25: arrBuffer.type = ArrayBuffer(11, 1, 3, 4, 5)
scala> arrBuffer
res26: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(11, 1, 3, 4, 5)
scala> arrBuffer.trim
trimEnd trimStart
scala> arrBuffer.trimEnd(3)
scala> arrBuffer
res28: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(11, 1)
11,移除一个数组中第一个负数以后的负数
val array = ArrayBuffer[Int]()
array +=(8,3,4,5,-15,8,-2,-100)
var firstNegative = false
var length = array.length
var indexed = 0
while(indexed < length)
{
if (array(indexed) >=0) {
indexed +=1
} else{
if (!firstNegative)
{
firstNegative = true;
indexed +=1
} else {
array.remove(indexed);
length -=1
}
}
println(array)
}
ArrayBuffer(8, 3, 4, 5, -15, 8, -2, -100)
ArrayBuffer(8, 3, 4, 5, -15, 8, -2, -100)
ArrayBuffer(8, 3, 4, 5, -15, 8, -2, -100)
ArrayBuffer(8, 3, 4, 5, -15, 8, -2, -100)
ArrayBuffer(8, 3, 4, 5, -15, 8, -2, -100)
ArrayBuffer(8, 3, 4, 5, -15, 8, -2, -100)
ArrayBuffer(8, 3, 4, 5, -15, 8, -100)
ArrayBuffer(8, 3, 4, 5, -15, 8)
12,
val n =10
def f1:Any = {
for(i<-1 to 10)
{
if(i == n)
return i
println(i)
}
}
f1
结果:
1
2
3
4
5
6
7
8
9
补充(转自 http://www.cppblog.com/abilitytao/archive/2014/10/04/208489.aspx)
scala中的数组比java的数组强大很多
1、定长数组:长度不变的数组Array,如:声明一个长度为10的整形数组,val arr = Array[Int](10);声明并初始化一个字符串数组: val arrStr = Array(“wo”,”cha”,”yo”)。访问数组方式:访问arrStr第一个元素,arrStr(1)即可
2、变长数组(即数组缓冲):java中有ArrayList和scala中的ArrayBuffer等效;但是ArrayBuffer更加强大,通过下面的事列来熟悉ArrayBuffer:
import collection.mutable.ArrayBuffer
val arrbuff1 = ArrayBuffer[Int]()
val arrBuff2 = ArrayBuffer(1,3,4,-1,-4)
arrbuff1 += 23 //用+=在尾端添加元素
arrbuff1 += (2,3,4,32) //同时在尾端添加多个元素
arrbuff1 ++= arrBuff2 //可以用 ++=操作符追加任何集合
arrbuff1 ++= Array(2,43,88,66)
arrbuff1.trimEnd(2) //移除最后的2个元素
arrbuff1.remove(2) //移除arr(2+1)个元素
arrbuff1.remove(2,4) //从第三个元素开始移除4个元素
val arr = arrbuff1.toArray //将数组缓冲转换为Array
val arrbuff2 = arr.toBuffer //将Array转换为数组缓冲
3、遍历数组和数组缓冲:在java中数组和数组列表/向量上语法有些不同。scala则更加统一,通常情况,我们可以用相同的代码处理这两种数据结构,for(…) yield 循环创建一个类型和原集合类型相同的新集合。for循环中还可以带守卫:在for中用if来实现。
for(i <- 0 until arrbuff1.length) yield arrbuff1(i) * 2 //将得到ArrayBuffer(2,6,4,-2,-4)
for(i <- 0 until (arrbuff1.length,2)) yield arrbuff1(i) * 2 //将得到ArrayBuffer(12,-4)
for(elem <-0 arrbuff1) print(elem) //如果不需要使用下标,用这种方式最简单了
for(i <- arrbuff1 if arrbuff1 > 0) print i //打印出arrbuff1中为整数的值
arrbuff1.filter( _ > 0).map{ 2 * _} //生成arrbuff1中的正数的两倍的新集合
arrbuff1.filter {_ > 0} map {2 * _} //另一种写法
4、常用算法:scala有很多便捷内建函数,如
arrbuff1.sum //对arrbuff1元素求和
Array("asd","sdf","ss").max //求最大元素
arrbuff1.sorted(_ < _) //将arrbuff1元素从小到大排序
arrbuff1.sorted(_ > _) //从大到小排序
util.Sorting.quickSort(Array) //针对数组排序,单不能对数组缓冲排序
val arr = Array(1,23,4,2,45)
arr.mkString(",") //指定分割符
arr.mkString("(",",",")") //指定前缀、分隔符、后缀
更多函数参见Scaladoc
5、多维数组:
val matrix = Array.ofDim[Int](5,4) //三行四列的二维数组
matrix(2)(3) //访问第二行、第三个元素
6、scala数组和java互操作:由于scala数组是用java数组实现的,所以可以在java和scala之间来回传递,引入scala.collectin.JavaConversion ,可以在代码中使用scala缓冲,在调用java方法时,这些对象会被自动包装成java列表。反过来讲,引入scala.collection.asScalaBuffer时,当java方法返回java.util.List时,我们可以让它转换成一个Buffer
变量定义:
val:类似java中final类型的变量
- 1,基本格式:val 变量名:变量类型 = 值
- 2,其中有时变量类型可以省略,可以自动识别
- 3,变量不能赋值,修改
scala> val age :Int=0 age: Int = 0 scala> var msg name:String = null <console>:1: error: illegal start of simple pattern var msg name:String = null ^ scala> var name:String = null name: String = null scala> val age1,age2,age3 =0 age1: Int = 0 age2: Int = 0 age3: Int = 0
函数定义
函数格式:
def 函数名(参数列表,...):返回结果类型={},下面给出一个max函数
1,有时函数必须制定返回结果类型,如函数时递归,就必须明确制定返回结果类型
2,在max这里例子中及时不写返回结果,编译器也能推断,如实这个函数就 编程如下的样子,作用功能都没有变化
3,如果函数仅 一个语句,连花括号都可以不写。如是max函数就成了这样,作用功能仍然没有变化
greeting():Unit,其中Unit值得时greetin的返回类型,类似于Java的void类型,而且Java中的void类型会被映射成Unit
def greeting()=println{"no args no return?"}
greeting()
greeting
结果两个都返回
no args no return?
no args no return?
while循环
Scala中,i++或者++i都不能其作用,只能使用i=i+1
var i = 0
while(i <= 5)
{
println("i is :" + i)
i++ //value ++ is not a member of Int
}
}
foreach与函数字面量
(x: Int, y:Int) => x + y
args.foreach(arg => println(arg))
args.foreach((arg: String) => println(arg))
args.foreach(println)
for循环
for循环中是val类型,因此在for表达式中不能重新对其赋值, <-可以理解为其中的意思,for(arg <- args) 对于args中的arg, 纳尼?怎么感觉是Java中foreach中的in