Scala作为Spark的开发语言,想要成为Spark高手,精通Scala是必须要走的一条路

然后一门语言并不是你想精通就能够精通的,更何况是Scala这种面向对象又面向函数的编程语言,个人觉得其学习的门槛会比C#,Java等面向对象语言要高

所以,这篇文章是建立在有一点编程语言知识的基础上的(如学过C#或者Java等),其实所有语言都是大同小异的,学会了一门语言在学其他的就不会像刚开始那么吃力了,因为它们很多概念都是相通的

本篇文章主要是介绍Scala本身的一些特性,以便以能够快速的上手开发,而对于真正要精通Scala,显然要付出的努力还要很多

安装Scala的开发环境就不具体介绍了,请自行百度之。IDE使用的是Eclipse For Scala,下载地址:

Eclipse For Scala

本文大概从以下几个方面来介绍Scala:

  1. 声明变量的关键字
  2. 方法的定义格式
  3. 条件表达式
  4. 默认参数,带名参数和变长参数
  5. lazy变量
  6. 数组
  7. Map操作
  8. 元组
  9. 值函数
  10. 匿名函数
  11. 函数柯里化
  12. 高阶函数示例
  13. List序列
  14. case class和模式匹配

Scala中声明变量的关键字只有两种:

val和var,分别表示常量和变量的声明(在Scala提倡中尽量使用val而不是var)

方法的定义格式:

def 方法名(参数名:参数类型,…):返回值类型={方法体}

如:

def add(x:Int,y:Int):Int={
x + y
}

定义了一个参数为两个Int类型,返回值也为Int类型的方法add,返回x+y的值

相信已经有人注意到了,在Scala中,每个句子是不用以分号结束的(当然加上分号也没事),而且方法中不用return来返回,默认返回的是最后一行的值

当方法没有返回值时表现形式为:

def add():Unit={...}

或者直接省略:Unit

def add()={...}

在调用方法的时候,如果该方法没有参数,可以省略括号,如:

add//加上括号也没事,如add()

条件表达式:

和其他语言的if/else唯一的却别就是,Scala的if/else是有返回值的

val x = 8
val res = if(x > 7) 1 else 0

如果x>7就返回1,否则返回0,赋值给res

Scala中的while和do-while用法是和其他语言一样的,但是for的用法就不同了

for循环语句的格式为:

for(i <- 表达式){
循环体
}

例如:

for(i <- 1 to 10){
println(i)
}

上面代码中,1 to 10会产生1-10中的每个数,i会迭代循环这10个数,迭代一次执行一次循环体。

刚开始看肯定会很奇怪,<-这个符号是必须的,现在假设我们有一个arr数组,里面有1-10这10个数

首先用C#的循环方式为:

for(int i = 0;i < arr.Length;i++)
{
Console.WriteLine(arr[i]);
}
//或者foreach方式
foreach(var i in arr)
{
Console.WriteLine(i);
}

在对比一下Scala的for循环:

for(i <- 0 to arr.length){
println(arr[i])
}
//for同时也可以当foreach使用
for(i <- arr){
println(i)
}

并且,在Scala中,for循环是可以添加if判断语句的,如:

for(i <- 0 to 10 if i % 2 == 0){
println(i)
}

上面代码的意思是,循环0-10,只打印出偶数

Scala的循环表达式中没有continue和break语句,但是可以通过一个Boolean变量和嵌套函数中return来实现

默认参数,带名参数和变长参数:

这几个概念很简单,通过几行实例代码基本可以了解

默认参数:

def getName(name:String = "JChubby") = {...}

调用getName时如果没有传参数,则会使用默认的JChubby

带名参数:

def showNum(x:Int,y:Int):Unit = {...}

调用该方法时,参数可以不按顺序,但是要执行参数名:

showNum(y = 2,x = 4)

变长参数:

def canChangeLength(x:Int*) = {...}

调用时:

canChangeLength(1,2,3,4,...)

lazy变量:

正常情况下使用val或者var声明变量时是直接分配内存空间使用的

当使用lazy关键字时,这个常/变量只有在使用的时候才会被分配内存

如在Scala命令行中输入下面的代码之后回车:

lazy val a = 1

lazy(懒值)对应开销很大的初始化操作非常有用,如在读取一个很大的文件的时候,如果一开始并不马上使用,可以将其标记为lazy,直到文件真正使用的时候才分配内存空间

数组:

Scala中分为两种:

定长数组:scala.collection.immutable.Array,一旦声明之后长度不可变

变长数组:scala.collection.mutable.ArrayBuffer,动态数组

定长数组使用:

val arr = new Array[Int](3)//声明长度为3,类型为Int的Array数组(new可省略)

//或者声明时直接赋值
//编译器会自动推断类型为Int
val arr = Array(1,2,3) //通过下标访问数组的方式为()而不是[],请注意!
val a = arr(0)

变长数组使用:

val arrBuf = scala.collection.mutable.ArrayBuffer[Int]()
//添加元素,相当于add
arrBuf += 1
//也可以一次性添加多个
arrBuf += (1,2,3)
//使用++=可以直接添加一个数组
arrBuf ++= Array(1,2,3)
//在指定位置插入若干个元素,在0位置插入1,2,3
arrBuf.insert(0,1,2,3)
//Scala中的函数除了通过.来调用之外也可以直接写成一下形式
arrBuf insert (0,1,2,3)
//之前的1 to 10 其实就是调用了1.to(10)这个to方法 //移除指定位置的元素
arrBuf remove 0
//移除指定位置后的连续n个元素
arrBuf remove 0,3
//删除末尾的n个元素
arrBuf trimEnd 3

此外还有例如min,max等函数求最大最小等常用操作

Map操作:

和数组一样,Map同样也分为可变和不可变两种

不可变Map的使用:

//声明一个Map,包含两个键值对,->表示键值对应的关系
val myMap = Map("JChubby" -> 22,"Looky" -> 21)

不可变的Map中,一旦声明之后,该Map不可添加不可删除不可修改,只能查看,查看方式与可变Map一致

可变Map的使用:

val myMap = scala.collection.mutable.Map("JChubby" -> 22,"Looky" -> 21)
//添加元素
myMap += ("abc" -> 12,"bcd" -> 13)
//删除元素
myMap -= "abc"
//修改元素
myMap("JChubby") = 10
//或者
myMap += ("JChubby" -> 10)
//查找元素
myMap("JChubby")
//或者使用getOrElse,该方法在取不到值的时候返回一个默认值,以免出现异常
myMap getOrElse ("JChubby",-1)
//遍历,使用的是k,v格式来进行遍历
for((k,v) <- myMap){
println(k + ":" + v)
}
//如果只要遍历k或者v,可以使用_占位符
for((k,_) <- myMap){
println(k)
}
//获取所有的key
myMap.keySet
//获取所有的value
myMap.values

元组:

元组其实就是一个集合,但是可以存放各种不同类型的数据

例如:

val group = (1,2,"JChubby",3.0)
//通过下标访问元组的格式为:元组名._下标 或者 元组名 _下标。如:
group._0
group _0
//遍历元组格式为,productIterator为固定格式不可少
for(element <- group.productIterator){
...
}

值函数:

Scala中可以将函数赋值给一个变量,这个变量就称为值函数

def add(x:Int,y:Int):Int = {
x + y
} //格式为方法名+空格+_
var res = add _
//之后可以将这个变量当做方法来用
res(1,2)

匿名函数:

顾名思义,没有名字的函数,定义格式如下:

(参数名:参数类型,…) => 表达式

例如:

(x:Int) => x + 3

可以将匿名函数赋值给一个常量

val func = (x:Int) => x + 3
//直接调用常量
func(7)

上面的用法其实和直接定义一个有名的函数是一样的,匿名函数主要是当做函数的参数来传递使用

例如scala.collection.mutable.ArrayBuffer的map方法,其参数要求是一个匿名函数

scala.collection.mutable.ArrayBuffer.map((x:Int) => x +3)

执行的结果是ArrayBuffer里面每个值都加3(map函数之后会介绍)

函数柯里化:

函数柯里化就是将原本有 很多参数 的函数,分成一个个只有 一个参数 的函数,每个函数的返回值都是 一个表达式 并且当做参数 传到下一个函数

例如:

def mul(x:Int,y:Int) = x + y
//调用方式为
mul(1,2)
//柯里化后的函数为
def mul(x:Int)(y:Int) = x + y
//调用当时为
mul(1)(2)
//执行mul(1)时,返回的是1 + y,在将这个函数应用到2,得到 1 + 2

柯里化是闭包的典型体现,具体柯里化的概念请百度之~

高阶函数示例:

数组的map函数

val arr = Array(1,2,3)
arr.map(1 + _)

_表示数组中的每个元素,执行的结果为每个元素+1

数组的filter函数

arr.filter(_ > 2)

_ > 2会将数组中大于2的元素过滤出来

数组的reduce函数

arr.reduce(_ + _)

reduce是迭代运算,将数组中两个元素先执行操作,把结果作为一个元素继续和下一个元素进行操作,执行结果为:1+2=3,3+3=9,也就是求和

List序列:

List操作:

val list = List(1,2,3)
//获取头元素
list.head
//获取除了头元素之外的其他元素
list.tail
//新增元素
7::list
//注意,::运算符是从右向左的 //获取前n个元素
list.take(n)
//list的zip操作
val list1 = List(a,b,c)
list.zip(list1)
//得到的结果为List((1,a),(2,b),(3,c)),如果两个list的长度不同,以比较短的为基础 //flatten操作
val list2 = List(List(1,2),List(2,3),List(3,4))
list2.flatten
//得到的结果为List(1,2,2,3,3,4),用于将嵌套List组合成一个新的List //flatmap操作
list2.flatmap(_.map(_ * 2))
//跟flatten相比,flatmap在组合之前,会先对每个子List进行map操作

case class和模式匹配:

case class又称为样例类,和普通的类相比,样例类不用new就可以实例化,默认执行的是apply方法来构造对象

模式匹配:

和其他语言的switch功能差不多,但是Scala里面使用的是match

使用示例:

val res = 1
res match{
case 0 => println(0)
case 1 => println(1)
case 2 => println(2)
}

除了用法格式上略有不同,其余的基本类似,并且不需要使用break关键字

样例类和模式匹配结合使用:

//定义抽象类Human
abstract class Human
//分别定义用例类Chinese,Japanese,American都继承自Human
case class Chinese(name:String) extends Human
case class Japanese(name:String) extends Human
case class American(name:String) extends Human //定义模式匹配方法
def caseMatch(human:Human){
//human参数类型不同,做出不同处理,Chinese(_)表示只关心是不是Chinese而不关心叫什么名字
case Chinese(_) => println("Chinese")
case Japanese(_) => println("Japanese")
case American(_) => println("American")
}

Spark(七) -- Scala快速入门的更多相关文章

  1. Spark记录-scala快速入门

    1.hello world程序 object HelloWorld { def main(args: Array[String]) { println("Hello,World!" ...

  2. spark之scala快速入门

    scala和java都是在jvm之上的语言,相对来讲,scala热度比较低,其实并不是一个特别好的语言选择. 原因倒不是因为scala本身的缺点,而是使用人群不够多,论坛和社区不够活跃.这就跟社交软件 ...

  3. Scala快速入门 - 基础语法篇

    本篇文章首发于头条号Scala快速入门 - 基础语法篇,欢迎关注我的头条号和微信公众号"大数据技术和人工智能"(微信搜索bigdata_ai_tech)获取更多干货,也欢迎关注我的 ...

  4. Scala快速入门(四)——继承、接口

    Scala快速入门(四)--继承.接口 一.继承 1.继承的概念:省略 2.模板: class Person(n:String,a:Int) { var name:String=n var age:I ...

  5. Scala快速入门到精通 视频教程 百度云网盘下载地址

    Scala快速入门到精通  视频教程 百度云网盘下载地址 Scala快速入门到精通 下载地址链接:https://pan.baidu.com/s/1bqGIKyF 密码:ojwd

  6. scala快速入门之文档注释

    scala快速入门之文档注释 1.在项目栏的目录树中找到该源码,右击点击Show in Explorer, 即可找到该源码的本地路径,在路径中输入cmd 2.执行scaladoc -d  生成文档注释 ...

  7. Scala快速入门-基础

    HelloWorld 从HelloWorld开始,使用scala IDE编辑器. 新建scala project 新建scala object 编写HelloWorld run as scala ap ...

  8. 【HTML+CSS】七小时快速入门~~~~~~~

    由于网络化的原因,学习很方便,但是也由于太方便了,学习资料很多会给刚想要入门却没有什么自制力的初学者造成困难,我自己来说学html和css先看了一本书,后来又辗转在慕课网.w3cschool等学习网站 ...

  9. Scala 快速入门

     Scalable 编程语言 纯正的的面向对象语言 函数式编程语言 无缝的java互操作 scala之父 Martin Odersky 1. 函数式编程 函数式编程(functional progr ...

随机推荐

  1. 字符设备驱动ioctl实现用户层内核层通信

    测试代码实现 memdev.h #ifndef _MEMDEV_H_ #define _MEMDEV_H_ #include<linux/ioctl.h> #ifndef MEMDEV_M ...

  2. import详解

    试想一下 在工作中今年在一个项目中可能会导入某一个目录下的模块文件,那这个时候怎么样才能让Python解释器能够找到该模块进行调用呢? - 将这个模块拷贝一份到当前使用目录下. 这种方式让模块太冗余 ...

  3. 【SQL】多个表的查询

    1.元组变量 SELECT * FROM a AS x, a AS y; 结果是显示自己和自己的笛卡尔乘积. 如果查询中对于某一个关系使用了多次,为了区别他们的属性,需要对关系定义别名,然后用 别名. ...

  4. 第一篇:Hello World

    Hello World RabbitMQ是一个消息代理:它接受和转发消息.你可以把它想象成一个邮局:当你把邮件放在邮箱里时,你可以确定邮差先生最终会把邮件发送给你的收件人.在这个比喻中,RabbitM ...

  5. VMware vCenter Server安装与配置

    预先准备好安装包 ESXI6    VMware-VMvisor-Installer-6.0.0.update01-3073146.x86_64.iso VC        VMware-VIMSet ...

  6. 自定义的一个JDBC工具类

    package JDBCutils; import java.io.File;import java.io.FileInputStream;import java.sql.Connection;imp ...

  7. UTC时间

    世界的每个地区都有自己的本地时间,在Internet及无线电通信时,时间的统一非常重要! 整个地球分为二十四时区,每个时区都有自己的本地时间.在国际无线电通信中,为统一而普遍使用一个标准时间,称为通用 ...

  8. C++指针和数组的区别(不能混用的情况)

    通常情况下,C++中指针和数组是可以混用的,但是,在编写字符数组的全排列的时候,混用却出了问题,因此,今天特地mark一下,以备日后查找 这里整理的,不包括用new开辟的动态数组 1.数组一旦声明,我 ...

  9. 训练指南 UVA - 11419(二分图最小覆盖数)

    layout: post title: 训练指南 UVA - 11419(二分图最小覆盖数) author: "luowentaoaa" catalog: true mathjax ...

  10. 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)

    layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" ca ...