您的位置:首页 > 其它

Scala光速入门之Scala的基本语法、Array、Map、Tuple等

2016-01-02 17:10 459 查看
首先很高兴能成为王老师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,_用法

scala中与_相关的用法还是挺多的:

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


10,ArrayBuffer

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

补充(转自/article/1988535.html):


变量定义:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: