scala学习

阅读了python和scala的优缺点的文章后,发现编程语言scala在学习spark上还是绕不过去的,不求很精通,但是熟悉基本的编写和使用是必须的。

第一步:scala的安装:
1、安装jdk1.8(略)
2、安装scala,官网http://www.scala-lang.org/download/all.html下载
3、安装设置idea,参考:https://blog.csdn.net/guiying712/article/details/68947747#1为什么要学习scala语言

初学使用subline3进行编程学习,
打开菜单栏Tool->build system->new build system,在打开文件敲入:
{
“cmd”: [“D:\your_scala_home\bin\scala.bat”, “$file”]
}
保存为自定义文件名就可以使用ctrl + B编译运行了

分支
if(){} else{}
有一点与Java不同的是,Scala中的if表达式的值可以赋值给变量,比如:
val x = 6
val a = if (x>0) 1 else -1
for 循环(to和until的区别,to包括边界数据,until不包括右边界数据)参考:https://blog.csdn.net/ycy258325/article/details/50561677
for (i <- 1 to 5 ){
for (j <- 1 to 3){println(i,j)}
}
for的推导式 如果使用() 那么需要用;隔开,也可以使用{} 就可以使用换行,就不需要;来隔开条件

var retVal = for{ var x <- List
     if condition1; if condition2...
}yield x

我们需要对上述过滤后的结果进行进一步的处理,这时,就可以采用yield关键字,对过滤后的结果构建一个集合

scala> for (i <- 1 to 5 if i%2==0) yield i(这里疑问,)
2.res3: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4)

while循环
do while循环
do{}while()

数据结构:scala判断一个数据或者对象的类型只需要在该对象后面添加 .getClass.getSimpleName :
数组:

类型:定长数组/变长数组
在Scala中,对数组元素的应用,是使用圆括号,而不是方括号,也就是使用intValueArr(0),而不是intValueArr[0],这个和Java是不同的。
声明定长数组:使用new Array() 定义一个可变的数组
val myStrArr = new ArrayString //声明一个长度为3的字符串数组,每个数组元素初始化为null
或者:val intValueArr = Array(12,45,33)
val myStrArr = Array(“BigData”,“Hadoop”,“Spark”)
声明变长数组:使用new ArrayBuffer() 定义一个可变的数组
val arr1 : ArrayBuffer[String] = new ArrayBufferString
数组的特性:元素的类型都相同,
数组的常用操作:https://blog.csdn.net/yu0_zhang0/article/details/79273257

以下是集合的组成部分:
列表:
声明列表:val intList = List(1,2,3)
列表的特性:元素的类型都相同,定义后不可变,列表具有递归的结构
参考:https://www.cnblogs.com/miqi1992/p/5635599.html
类List没有提供append操作,因为随着列表变长append的耗时将呈线性增长,而使用::做前缀则仅花费常量时间。如果你想通过添加元素来构造列表,你的选择是把它们前缀进去,当你完成之后再调用reverse;或使用ListBuffer,一种提供append操作的可变列表,当你完成之后调用toList

元组:
声明方式:val t = (1, “hello”, Console)或者val t = Tuple3(1, “hello”, Console)
元组是类型Tuple1,Tuple2,Tuple3等等。目前在Scala中只能有22个上限,如果您需要更多个元素,那么可以使用集合而不是元组。 对于每个TupleN类型,其中上限为1 <= N <= 22
元组使用tuple.productIterator进行迭代

scala中Array(ArrayBuffer)、List、Tuple异同
从数据结构的角度:
 1)Array、List、Tuple都是不可变长的,BufferArray是可变长的
 2)Array和List中的元素类型必须相同,Tuple可以存放不同的类型
 3)Array元素可变,List、Tuple元素不可变
访问的角度:
 1)Array、List都是从下标0开始访问,形式为Array(0)、List(0)
 2)Tuple从下标1开始访问,形式为Tuple._1
声明方式不同

集(set)是不重复元素的集合。列表中的元素是按照插入的先后顺序来组织的,但是,”集”中的元素并不会记录元素的插入顺序,而是以“哈希”方法对元素的值进行组织,所以,它允许你快速地找到某个元素。集包括可变集和不可变集,缺省情况下创建的是不可变集,通常我们使用不可变集
声明方式:var set1 = Set(“Hadoop”,"Spark)
这段讲解需要注意http://dblab.xmu.edu.cn/blog/949-2/

scala函数和方法:
scala类:
声明一个类

class Counter {
    private var value = 0
    def increment(): Unit = { value += 1}
    def current(): Int = {value}
}

scala没有专门的getter和setter方法:但是可以实现:
具体实现:
Scala又没有提供getter和setter方法,怎么可以访问value字段呢?解决方案是,在Scala中,可以通过定义类似getter和setter的方法,分别叫做value和value_=,具体如下:

class Counter {
    private var privateValue = 0  //变成私有字段,并且修改字段名称
    def value = privateValue //定义一个方法,方法的名称就是原来我们想要的字段的名称
    def value_=(newValue: Int){
        if (newValue > 0) privateValue = newValue //只有提供的新值是正数,才允许修改
    }
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
}
object MyCounter{
    def main(args:Array[String]){
        val myCounter = new Counter
        println(myCounter.value)  //打印value的初始值
        myCounter.value = 3 //为value设置新的值
        println(myCounter.value)  //打印value的新值 
        myCounter.increment(1) //这里设置步长为1,每次增加1
        println(myCounter.current)
    }
}

构造器:Scala构造器包含1个主构造器和若干个(0个或多个)辅助构造器。
我们首先认识一下辅助构造器。辅助构造器的名称为this,每个辅助构造器都必须调用一个此前已经定义的辅助构造器或主构造器。
Scala的每个类都有主构造器。但是,Scala的主构造器和Java有着明显的不同,Scala的主构造器是整个类体,需要在类名称后面罗列出构造器所需的所有参数,这些参数被编译成字段,字段的值就是创建对象时传入的参数的值
scala对象:
单例对象:声明一个单例对象:

object Person {
    private var lastId = 0  //一个人的身份编号
    def newPersonId() = {
        lastId +=1
        lastId
    }
}

伴生对象:
在Java中,我们经常需要用到同时包含实例方法和静态方法的类,在Scala中可以通过伴生对象来实现。当单例对象与某个类具有相同的名称时,它被称为这个类的“伴生对象”。类和它的伴生对象必须存在于同一个文件中,而且可以相互访问私有成员(字段和方法)。

class Person {
    private val id = Person.newPersonId() //调用了伴生对象中的方法
    private var name = ""
    def this(name: String) {
        this()
        this.name = name
    }
    def info() { printf("The id of %s is %d.\n",name,id)}
}
object Person {
    private var lastId = 0  //一个人的身份编号
    private def newPersonId() = {
        lastId +=1
        lastId
    }
    def main(args: Array[String]){
        val person1 = new Person("Ziyu")
        val person2 = new Person("Minxing")
        person1.info()
        person2.info()      
    }
}

scala继承:

Scala中的继承与Java有着显著的不同:
(1)重写一个非抽象方法必须使用override修饰符。
(2)只有主构造器可以调用超类的主构造器。
(3)在子类中重写超类的抽象方法时,不需要使用override关键字。
(4)可以重写超类中的字段。
Scala和Java一样,不允许类从多个超类继承

抽象类:声明一个抽象类:

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

关于上面的定义,说明几点:
(1)定义一个抽象类,需要使用关键字abstract。
(2)定义一个抽象类的抽象方法,也不需要关键字abstract,只要把方法体空着,不写方法体就可以。
(3)抽象类中定义的字段,只要没有给出初始化值,就表示是一个抽象字段,但是,抽象字段必须要声明类型,比如:val carBrand: String,就把carBrand声明为字符串类型,这个时候,不能省略类型,否则编译会报错。
抽象类不能直接被实例化,所以,下面我们定义几个扩展类,它们都是扩展了Car类,或者说继承自Car类。

class BMWCar extends Car {
    override val carBrand = "BMW"  //重写超类字段,需要使用override关键字,否则编译会报错
    def info() {printf("This is a %s car. It is on sale", carBrand)} //重写超类的抽象方法时,不需要使用override关键字,不过,如果加上override编译也不错报错
    override def greeting() {println("Welcome to my BMW car!")} //重写超类的非抽象方法,必须使用override关键字
}

scala特质:
Java中提供了接口,允许一个类实现任意数量的接口。在Scala中没有接口的概念,而是提供了“特质(trait)”,它不仅实现了接口的功能,还具备了很多其他的特性。Scala的特质,是代码重用的基本单元,可以同时拥有抽象方法和具体方法。Scala中,一个类只能继承自一个超类,却可以实现多个特质,从而重用特质中的方法和字段,实现了多重继承。
特质声明:

trait CarId{
  var id: Int
    def currentId(): Int     //定义了一个抽象方法
}

举个例子:

trait CarId{
  var id: Int
    def currentId(): Int     //定义了一个抽象方法
}
trait CarGreeting{
  def greeting(msg: String) {println(msg)}  
}
class BYDCarId extends CarId with CarGreeting{ //使用extends关键字混入第1个特质,后面可以反复使用with关键字混入更多特质
   override var id = 10000 //BYD汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 }
 class BMWCarId extends CarId with CarGreeting{ //使用extends关键字混入第1个特质,后面可以反复使用with关键字混入更多特质
   override var id = 20000 //BMW汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 } 
 object MyCar { 
    def main(args: Array[String]){
        val myCarId1 = new BYDCarId()       
        val myCarId2 = new BMWCarId()
        myCarId1.greeting("Welcome my first car.")
        printf("My first CarId is %d.\n",myCarId1.currentId)        
        myCarId2.greeting("Welcome my second car.")
        printf("My second CarId is %d.\n",myCarId2.currentId)
    }
}

scala模式匹配:
例子:
object test {
def main(args: Array[String]): Unit = {
for(elem <- List(9,12.3,“Spark”,“Hadoop”,'Hello)){
val str = elem match {#str 为返回的数据
case i : Int => i + " is Int" #判断类型,可以是使用不同的变量i,d,s,unexpected 等
case d : Double => d + " is Double"
case “Spark” => “Spark is not found”
case s : String => s + " is String"
case unexpected => unexpected + " This is an unexpected value "
}
println(str)
}
}
}

在Scala中,使用Option的情形是非常频繁的。在Scala里,经常会用到Option[T]类型,其中的T可以是Sting或Int或其他各种数据类型。Option[T]实际上就是一个容器,我们可以把它看做是一个集合,只不过这个集合中要么只包含一个元素(被包装在Some中返回),要么就不存在元素(返回None)。既然是一个集合,我们当然可以对它使用map、foreach或者filter等方法。比如:.get(“hive”).foreach(println)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值