Spark学习(一)——Scala基础学习

笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值,找寻数据的秘密,笔者认为,数据的价值不仅仅只体现在企业中,个人也可以体会到数据的魅力,用技术力量探索行为密码,让大数据助跑每一个人,欢迎直筒们关注我的公众号,大家一起讨论数据中的那些有趣的事情。

我的公众号为:livandata

scala是一门多范式编程语言,集成了面向对象编程和函数式编程等多种特性。

scala运行在虚拟机上,并兼容现有的Java程序。

Scala源代码被编译成java字节码,所以运行在JVM上,并可以调用现有的Java类库。

1、第一个Scala程序:

Scala和Java最大的区别是:Scala语句末尾的分号(;)是可选的!

编译运行:

先编译:scalac HelloScala.scala   将会生成两个文件:HelloScala$.class和HelloScala.class

在运行:scala HelloScala

输出结果:hello scala!!!

object HelloScala{

  def main(args: Array[String]): Unit = {

    println("hello scala!!!")

  }

}

2、Scala基本语法:

1) 区分大小写;

2) 类名首字母大写(MyFirstScalaClass);

3) 方法名称第一个字母小写(myMethodName());

4) 程序文件名应该与对象名称完全匹配;

5) defmain(args:Array[String]): scala程序从main方法开始处理,程序的入口。

6) Scala注释:分为多行/**/和单行//

7) 换行符:Scala是面向行的语言,语句可以用分号(;)结束或换行符(println())

8) 定义包有两种方法:

其一:package com.ahu

      classHelloScala

其二:package com.ahu{

      class HelloScala

  }

引用:import java.awt.Color

如果想要引入包中的几个成员,可以用selector(选取器):

importjava.awt.{Color,Font}

// 重命名成员

importjava.util.{HashMap => JavaHashMap}

// 隐藏成员 默认情况下,Scala 总会引入 java.lang._ 、 scala._ 和 Predef._,所以在使用时都是省去scala.的

importjava.util.{HashMap => _, _} //引入了util包所有成员,但HashMap被隐藏了

3、Scala数据类型:

Scala与Java有着相同的数据类型,下面列出一些Scala有的数据类型。

Unit:表示无值,和其他语言的void一样,一般函数返回时如果没有返回值,可以添加返回值为Unit。

Null:null或空引用。

Nothing:是Scala的类层级的最低端,是任何其他类型的子类型。

Any:是所有其他类的父类。

AnyRef:是Scala所有引用类的父类。

多行字符串的表示方法:

val foo="""第一行

                 第二行

                 第三行"""

4、Scala变量:

在Scala中,使用关键字“var”声明变量,使用关键字“val”声明常量。

var myVar1 : String= "foo"

val myVal ="Hello,Scala!"

Scala多个变量声明:

val xmax, ymax =100  // xmax,ymax都声明为100

Scala访问修饰符:

Scala访问修饰符和Java基本一样,分别有private、protected、public。

默认情况下,Scala对象的访问级别是public。

私有成员:用private关键字修饰的成员仅在包含了成员定义的类或对象内部可见。

class Outer{

  class Inner{

    private def f(){println("f")}

    class InnerMost{

      f() // 正确

    }

  }

  (new Inner).f() // 错误

}

保护成员:Scala比Java中更严格。只允许保护成员在定义了该成员的类的子类中被访问,而在java中除了子类可以访问,同一个包里的其他类也可以进行访问。

package p{

  class Super{

       protecteddef f() {println("f")}

  }

  class Sub extends Super{

     f()

  }

  class Other{

     (new Super).f()  // 错误

  }

}

公共成员:默认public,这样的成员在任何地方都可以被访问。

class Outer{

  class Inner{

    def f(){println("f")}

    class InnerMost{

      f() // 正确

    }

  }

  (new Inner).f() // 正确

}

5、作用域保护:Scala中,访问修饰符可以通过使用限定词强调。

private[x] 或者 protected[x]

private[x]:这个成员除了对[...]中的类或[...]中的包中的类及他们的伴生对象可见外,对其他的类都是private。

Scala运算符:和Java一样,这里就不再浪费时间一一介绍了。

算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符。

Scala if...else语句:和Java一样,简单列举一下四种情况。

if(...){

}

if(...){

}else{

}

if(...){

}else if(...){

}else{

}

if(...){

  if(...){

  }

}

Scala循环:和Java一样,这里不赘述,只介绍三种循环类型。

while循环、do...while循环、for循环

6、Scala函数:scala中函数的地位是非常高的,因此,其变换相对比较多。

option[T]有两个子类别:some与none;

option[String] =Some(Paris):返回string类型或者none;

当程序回传some的时候,代表这个函数式成功的返回了一个String值,可以通过get()获取到;如果程序返回none,则代表没有字符串给你,此时如果通过get()获取option中的值,就会报错;

object Test{

  def main(args: Array[String]){

    println(addInt(1,3)); // 函数调用

  }

函数的定义流程:

def addInt(a:Int,b:Int):Int = {

   var c:Int = 0

   c = a+b

   return c

}

传名调用:

def time()={

   println("获取时间,单位为纳秒")

   System.nanoTime

}

def delayed( t :=> Long )={

   println("在delay方法内")

   println("参数:"+t)

   t

}

命名参数:

def printInt(a:Int,b:Int)={

   println("value of a :"+a)

   println("value of b :"+b)

}

可变参数:不需要指定参数的个数

defprintStrings(args:String*)={

   var i:Int = 0;

   for (arg<-args){

      println("argvalue["+i+"]="+arg);

      i = i +1

     }

}

递归函数:

deffactorial(n:BigInt):BigInt={

   if(n<=1)

     1

   else

     n*factorial(n-1)

}

默认参数值:

def addInt(a:Int =5, b:Int = 7):Int={

   var sum:Int = 0

   sum = a + b

   return sum

}

高阶函数:操作其他函数的函数

defapply(f:Int=>String, v:Int)={

   f(v)

}

函数嵌套:

def factorial(i:Int):Int= {

   def fact(i:Int, accumulator:Int):Int={

      if(i<=1){

          accumulator

      }else{

          fact(i-1, i*accumulator)

      }

   }

   fact(i, 1)

}

匿名函数:箭头左边是参数列表,右边是函数体;

var inc = (x:Int)=> x+1

函数柯里化:

原函数为:

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

defadd(x:Int)(y:Int)=x+y

类似于:

defadd(x:Int)=(y:Int)=>x+y

即转化为调用两次的一维函数

val result =add(1)(2)

}

7、Scala闭包:

闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。

例子:

object Test{

def main(args:Array[String]){

   println("muliplier(1) value = " +muliplier(1))

   println("muliplier(2) value = " +muliplier(2))

}

var factor = 3  // 定义在函数外的自由变量

val muliplier =(i:Int) => i * factor  // muliplier函数变量就是一个闭包

}

输出结果:

muliplier(1) value= 3

muliplier(2) value= 6

8、Scala字符串:

Scala中可以创建两中字符串:一种是不可修改的,一种是可以修改的。

// 创建不可修改的字符串

var greeting:String= "Hello World!";

// 创建可以修改的字符串

object Test{

  def main(args: Array[String]){

    val buf = new StringBuilder;

    buf += 'a' // 添加一个字符

    buf ++= "bcdef" // 添加一个字符串

    println(buf.toString);  // 输出:abcdef

  }

}

字符串长度:xxx.length()

字符串连接:可以用concat()方法或者用加号

object Test {

  def main(args: Array[String]) {

    var str1 = "字符串1:";

    var str2 = "字符串2";

    var str3 = "字符串3:";

    var str4 = "字符串4";

    println( str1 + str2 ); //  字符串1:字符串2

    println( str3.concat(str4) ); // 字符串3:字符串4

  }

}

创建格式化字符串:

String类中可以使用printf()方法来格式化字符串并输出。

object Test{

  def main(args:Array[String]){

    var floatVar = 12.456

    var intVar = 2000

    var stringVar = "字符串变量"

    var fs = printf("浮点型变量为 " +"%f,整形变量为 %d, 字符串为 " +"%s", floatVar, intVar, stringVar)

    println(fs) // 浮点型变量为 12.456000, 整型变量为 2000, 字符串为 字符串变量

  }

}

特殊符号:

->:  map中的应用,类似于:                    

<-:  用于遍历集合对象;                        

=>:  1)by name运算:将函数传入by name参数;  

       2)函数类型:定义函数                    

       3)模式识别:case "1" =>"one"           

       4)匿名函数的应用                        

<=: 小于等于号                                

::  向队列头部追加数据,x::list              

:+  在尾部追加数据;                         

+:  在头部追加数据;                         

++  连接两个集合;set1++set2                  

:::  用于连接两个list类型的集合;list1:::list2

正则表达式:

val pattern ="Scala".r                                                      

val str ="Scala is Scalable and scala is good"                          

try{                                                                     

   println(pattern findFirstIn str)                                      

   println((pattern findAllInstr).mkString(","))                        

   println(pattern replaceFirstIn(str,"Java"))                          

   println(pattern replaceAllIn(str,"Java"))                            

  }catch{                                                                

      case ex:FileNotFoundException =>{println("Missing file Exception")}

      case ex:IOException =>{println("IO Exception")}                   

  }finally{                                                              

      println("Exitingfinally~")                                        

  }

常见正则表达式符号:

\:       转义字符;

^:      匹配输入字符串开始的位置;

$:       匹配输入字符串结束的位置;

*:       零次或多次匹配前面的字符或子表达式;

+:      一次或多次匹配前面的字符或子表达式;

?:       零次或一次匹配前面的字符或子表达式;

{n}:     正好匹配n次;

{n.}:    至少匹配n次;

{n,m}: 匹配n到m次;

贪心模式:(.*?)

非贪心模式:(.*)

9、Scala数组:

1)声明数组

  var z:Array[String] = newArray[String](3)  或者  varz = new Array[String]()

  z(0) = "value1"; z(1) ="value2"; z(2) = "value3"

  var z = Array("value1","value2", "value3")

2)处理数组

  object Test{

    def main(args: Array[String]){

      var myList = Array(1.1, 2.2, 3.3, 4.4)

      // 输出所有数组元素

      for(x <- myList){

        println(x)

      }

      // 计算数组所有元素的总和

      var total = 0.0

      for(i <- 0 to (myList.length - 1)){

        total += myList(i)

      }

      println("总和:" + total)

      // 查找数组中的最大元素

      var max = myList(0)

      for(i <- 1 to (myList.length - 1)){

        if(myList(i) > max)

          max = myList(i)

      }

      println("最大值:" + max)

    }

  }

3)多维数组

import Array._

object Test{

  def main(args: Array[String]){

    // 定义数组

    var myMatrix = ofDim[Int](3,3)

    // 创建矩阵

    for(i <- 0 to 2){

      for(j <- 0 to 2){

        myMatrix(i)(j) = j;

      }

    }

    // 打印矩阵

    for(i <- 0 to 2){

      for(j <- 0 to 2){

        print(" " + myMatrix(i)(j));

      }

      println();

    }

  }

}

4)合并数组

import Array._

object Test{

  defmain(args: Array[String]){

    var myList1 = Array(1.1, 2.2, 3.3, 4.4)

    var myList2 = Array(5.5, 6.6, 7.7, 8.8)

    // 使用concat()合并

    var myList3 = concat(myList1, myList2)

    // 输出所有数组元素

    for(x <- myList3){

      println(x)

    }

  }

}

5)创建区间数组:使用range(x,y,z)创建区间数组,数值范围大于等于x,小于y。z表示步长,默认为1。

object Test{

  def main(args: Array[String]){

    var myList1 = range(10, 20, 2)

    var myList2 = range(10, 20)

    for(x <- myList1){

      print(" " + x)  //输出:10 12 14 16 18

    }

    println()

    for(x <- myList2){

      print(" " + x)  // 输出:10 11 12 13 14 15 16 17 18 19

    }

  }

}

10、Scala集合:分为可变集合和不可变集合。

可变集合:可以在适当的地方被更新或扩展,也就是可以修改、添加、移除一个集合的元素。

不可变集合:永远不会改变。但可以模拟添加、移除、更新操作,但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变。

// 定义整形List

val x =List(1,2,3,4)

// 定义Set

var x =Set(1,3,5,7)

// 定义Map

val x =Map("one" -> 1, "two" -> 2, "three" ->3)

// 创建两个不同类型的元组

val x = (10,"Runoob")

// 定义Option:如果有值返回int型,如果没有值返回none;

val x:Option[Int] =Some(5)

11、Scala迭代器:

迭代器不是一个集合,而是一个用于访问集合的方法。

object Test{

def main(args:Array[String]): Unit = {

  val it = Iterator("one","two", "three", "four")

  while(it.hasNext){  // 检测集合中是否还有元素

    println(it.next())  // 返回迭代器的下一个元素,并更新迭代器的状态

  }

  val ita = Iterator(1, 2, 3, 4, 5)

  val itb = Iterator(11, 22, 33, 44, 55)

  //println(ita.max)  // 查找最大元素

  //println(itb.min)  // 查找最小元素

  println(ita.size) // 获取迭代器的长度

  println(itb.length) // 获取迭代器的长度

}

12、Scala类和对象:

类是对象的抽象,对象是类的具体实例。

类是抽象的,不占用内存;对象是类的具体实例,占用存储空间。

scala中object与class的区别:

class是指一般的类;

object是指静态类,类似于java中的static;

import java.io._

class Point(xc:Int, yc: Int){

  var x: Int = xc

  var y: Int = yc

  def move(dx: Int, dy: Int): Unit ={

    x = x + dx

    y = y + dy

    println("x点的坐标是:" + x)

    println("y点的坐标是:" + y)

  }

}

object Test{

  def main(args: Array[String]): Unit = {

    val pt = new Point(10, 20)

    // 移到一个新的位置

    pt.move(10, 10)

  }

}

13、Scala继承:跟Java差不多。

1)重写类参数、非抽象方法需要用到override修饰符

2)只有主构造函数才可以往基类的构造函数中写参数;

3)在子类中重写超类的抽象方法时,不需要使用override关键字;

class Point(val xc:Int, val yc: Int){

  var x: Int = xc

  var y: Int = yc

  def move(dx: Int, dy: Int): Unit ={

    x = x + dx

    y = y + dy

    println("x点的坐标是:" + x)

    println("y点的坐标是:" + y)

  }

  //-------------------------------------

  var name = ""

  override def toString = getClass.getName +"[name=" + name + "]"

}

classLocation(override val xc: Int, override val yc: Int, val zc: Int)

         extends Point(xc, yc){  // 继承:重写了父类的字段

  var z: Int = zc

  def move(dx: Int, dy: Int, dz: Int){

    x = x + dx

    y = y + dy

    z = z + dz

    println("x点的坐标是:" + x)

    println("y点的坐标是:" + y)

    println("z点的坐标是:" + z)

  }

  //---------------------------------------

  var salary = 0.0

  override def toString = super.toString +"[salary=" + salary + "]"

}

object Test{

  def main(args: Array[String]): Unit = {

    val loc = new Location(10, 20, 30)

    loc.move(10, 10 ,5)

    //------------------------------------

    loc.name = "lc"

    loc.salary = 35000.0

    println(loc)

  }

}

14、Scala单例对象:

Scala中没有static,要使用object关键字实现单例模式。

Scala中使用单例模式时,除了定义类,还要定义一个同名的object对象,它和类的区别是,object对象不能带参数。

当单例对象与某个类共享一个名称时,他被称作这个类的伴生对象。

必须在同一个源文件里定义类和它的伴生对象。

类和它的伴生对象可以互相访问其私有成员。

私有构造方法:

class Markerprivate(val color:String) {

  println("创建" + this)

  override def toString(): String = "颜色标记:"+ color  //4:颜色标记:red

}

伴生对象:与类共享名字,可以访问类的私有属性和方法。

object Marker{

  private val markers: Map[String, Marker] =Map(

    "red" -> newMarker("red"), //1:创建颜色标记:red

    "blue" -> newMarker("blue"), //2:创建颜色标记:blue

    "green" -> newMarker("green")  //3:创建颜色标记:green

  )

  def apply(color:String) = {

    if(markers.contains(color)) markers(color)else null

  }

  def getMarker(color:String) = {

    if(markers.contains(color)) markers(color)else null  //5:颜色标记:blue

  }

  def main(args: Array[String]) {

    println(Marker("red"))

    // 单例函数调用,省略了.(点)符号

    println(Marker getMarker "blue")

  }

}

15、Scala Trait(特征):

相当于Java的接口,但比接口功能强大,它还可以定义属性和方法的实现。

一般情况下Scala的类只能单继承,但特征可以实现多重继承。

定义特征:

trait Equal{

  def isEqual(x: Any): Boolean  // 未实现的方法

  def isNotEqual(x: Any): Boolean = !isEqual(x)// 实现了的方法

}

class Point(xc: Int,yc: Int) extends Equal{

  var x: Int = xc

  var y: Int = yc

  override def isEqual(obj: Any): Boolean =

  obj.isInstanceOf[Point] &&

  obj.asInstanceOf[Point].x == x

}

object Test{

  def main(args: Array[String]): Unit = {

    val p1 = new Point(2, 3)

    val p2 = new Point(2, 4)

    val p3 = new Point(3, 3)

    println(p1.isNotEqual(p2))

    println(p1.isNotEqual(p3))

    println(p1.isNotEqual(2))

  }

}

16、特征构造顺序:

构造器的执行顺序:

1)调用超类的构造器

2)特征构造器在超类构造器之后、类构造器之前执行

3)特征由左到右被构造

4)每个特征当中,父特征先被构造

5)如果多个特征共有一个父特征,父特征不会被重复构造

6)所有特征被构造完毕,子类被构造

Scala模式匹配:选择器 match {备选项}

object Test{

  def main(args: Array[String]): Unit = {

       println(matchTest("two"))

       println(matchTest("test"))

       println(matchTest(1))

       println(matchTest(6))

  }

  def matchTest(x: Any): Any = x match {

       case1 => "one"

       case"two" => 2

       casey: Int => "scala.Int"  // 对应类型匹配

       case_ => "many"  // 默认全匹配选项

  }

}

使用样例类:

使用case关键字的类定义就是样例类,样例类是种特殊的类,经过优化以用于模式匹配。

object Test{

  def main(args: Array[String]): Unit = {

    val alice = new Person("Alice",25)

    val bob = new Person("Bob", 32)

    val charlie = newPerson("Charlie", 27)

    for(person <- List(alice, bob,charlie)){

      person match{

        case Person("Alice", 25)=> println("Hi Alice!")

        case Person("Bob", 32) =>println("Hi Bob!")

        case Person(name, age) =>println("Age: " + age + " year,name: " + name+"?")

      }

    }

  }

  // 样例类

  case class Person(name: String, age: Int)

}

17、Scala异常处理:

和Java类似。在Scala中借用了模式匹配的方法来在catch语句块中来进行异常匹配。

importjava.io.{FileNotFoundException, FileReader, IOException}

object Test{

  def main(args: Array[String]): Unit = {

    try {

      val f = newFileReader("input.txt")

    }catch {

      case ex: FileNotFoundException => {

        println("Missing fileexception")

      }

      case ex: IOException => {

        println("IO Exception")

      }

    }finally {

      println("Exiting finally...")

    }

  }

}

18、Scala提取器(Extractor):

apply方法:无需new操作就可创建对象。

unapply方法:是apply方法的反向操作,接受一个对象,然后从对象中提取值,提取的值通常是用来构造对象的值。

object Test {

         def main(args: Array[String]) {

                  println("Apply 方法 : " + apply("Zara","gmail.com"));

                  //也可直接Test("Zara","gmail.com")来创建Zara@gmail.com

                  println("Unapply 方法 : " +unapply("Zara@gmail.com"));

                  println("Unapply 方法 : " + unapply("Zara Ali"));

         }

         // 注入方法 (可选)

         def apply(user: String, domain: String)= {user +"@"+ domain}

         // 提取方法(必选)

         def unapply(str: String):Option[(String, String)] = {

                val parts = str split "@"

                if (parts.length == 2){

             Some(parts(0), parts(1))

                }else{

             None

                }

         }

}

19、提取器使用模式匹配:

在我们实例化一个类的时,可以带上0个或者多个的参数,编译器在实例化的时会调用 apply 方法。

object Test {

         def main(args: Array[String]) {

       valx = Test(5)

                println(x)

       xmatch

       {

    caseTest(num) => println(x + " 是 " + num + " 的两倍!")  //2:10是5的两倍!

    //unapply被调用

    case_ => println("无法计算")

       }

         }

         def apply(x: Int) = x*2 //1:10

         def unapply(z: Int): Option[Int] = if(z%2==0) Some(z/2) else None

}

20、Scala文件I/O:

文件写操作

import java.io._

object Test {

  def main(args: Array[String]) {

     val writer = new PrintWriter(newFile("test.txt" ))

     writer.write("Scala语言")

     writer.close()

   }

 }

// 从屏幕上读取用户输入

object Test {

   def main(args: Array[String]) {

     print("请输入菜鸟教程官网 : " )

     val line = Console.readLine // 在控制台手动输入

     println("谢谢,你输入的是: " + line)

   }

 }

// 从文件上读取内容

importscala.io.Source

object Test {

   def main(args: Array[String]) {

     println("文件内容为:" )

     Source.fromFile("test.txt").foreach{

       print

     }

   }

 }

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值