• spark之scala快速入门


    scala和java都是在jvm之上的语言,相对来讲,scala热度比较低,其实并不是一个特别好的语言选择。

    原因倒不是因为scala本身的缺点,而是使用人群不够多,论坛和社区不够活跃。这就跟社交软件一样,大家都用微信,短信就没人用了。

    但是scala是写分布式程序的一门非常方便的语言,因为scala几乎每个对象都有map,reduce,filter等方法,这跟spark的用法简直如出一辙。

    多范式

    scala是一种多范式的语言,这也没啥特别的,就是既能面向过程又能面向对象,比如C++就是多范式。

    安装

    装scala要先装java,再装scala。

    交互式编程

    scala支持像javascript那种交互式编程,在命令行输入scala,进入交互式编程控制台。

    编译

    scalac 约等于 javac

    打包和引包

    打包有两种,第一种和java一样,在首行用package关键字。先掌握这种就行了。

    引包也是用import但功能比java要强大,可以在代码任意位置引。

    import java.awt.{Color, Font}
     
    // 重命名成员
    import java.util.{HashMap => JavaHashMap}
     
    // 隐藏成员
    import java.util.{HashMap => _, _} // 引入了util包的所有成员,但是HashMap被隐藏了

    默认情况下,Scala 总会引入 java.lang._ 、 scala._ 和 Predef._,这里也能解释,为什么以scala开头的包,在使用时都是省去scala.的。

    数据类型

    scala多了几种比较傻又还是有点用的数据类型:

    Unit 类似于void

    Null 等于null

    Nothing 是所有类的子类

    Any 约等于 Object

    常量和变量声明

    常量: val x:String ="a";

    变量  var x:String ="a";

    访问修饰符

    private ,protect,public default是public。有一些些区别,比如可灵活指定范围 private[ClassA]表示ClassA能访问。

    运算符

    基本运算符完全一致,不用特地去看。

    针对集合或者是特殊对象有一些运算符,如List中(::,:::),Set中(&,++)等,运算符也可以作为方法使用。

    if...else

    完全一致,不用特地去看。

    循环

    终止循环。scala不支持break和continue关键字,scala2.8之后加入了 Breaks类,使用如下写法:

    // 导入以下包
    import scala.util.control._
    
    // 创建 Breaks 对象
    val loop = new Breaks;
    
    // 在 breakable 中循环
    loop.breakable{
        // 循环
        for(...){
           ....
           // 循环中断
           loop.break;
       }
    }

    for循环比较好用,java感觉也是借鉴了该思想:

    //1到10
    for( var x <-  1 to 10 ){
       statement(s);
    }
    
    //1到9
    for( var x <-  1 until 10 ){
       statement(s);
    }
    
    //双循环,java里面需要两个for
    for( a <- 1 to 3; b <- 1 to 3){
             println( "Value of a: " + a );
             println( "Value of b: " + b );
          }
    
    
    //集合
    for(x<- List)
    {
    }
    
    //循环过滤 感觉不需要掌握,放在循环体内也可以。
          for( a <- numList
               if a != 3; if a < 8 ){
             println( "Value of a: " + a );
          }
    
    //yield  注意for后面是大括号 用于返回满足条件的所有a集合里面的值,生成新集合
          var retVal = for{ a <- numList 
                            if a != 3; if a < 8
                          }yield a

    方法声明

    在java中是先声明出参再声明入参,scala正好相反。只是思维方式不一样。

    object add{
       def addInt( a:Int, b:Int ) : Int = {
          var sum:Int = 0
          sum = a + b
    
          return sum
       }
    }

    函数声明

    函数是scala函数式编程的重点,会在下一篇文章中重点介绍。

    字符串

    scala字符串是不能更新的所以对字符串变量的修改会在内存区域创建一个新的字符串对象,如果需要更新,可以用StringBuilder这个对象。

    集合:

    scala集合包括java中常见的那些集合(List,Set,Map),以及元组,与java不同的是,scala中的集合一般是不可变集合,修改集合的实现是创建一个新的集合。

    链表(List)

    列表的元素类型 T 可以写成 List[T]。

    构造列表的两个基本单位是 Nil 和 ::  。 Nil 也可以表示为一个空列表。

    scala的类java构造数组办法。

    // 字符串列表
    val site: List[String] = List("Runoob", "Google", "Baidu")
    
    // 整型列表
    val nums: List[Int] = List(1, 2, 3, 4)
    
    // 空列表
    val empty: List[Nothing] = List()
    
    // 二维列表
    val dim: List[List[Int]] =
       List(
          List(1, 0, 0),
          List(0, 1, 0),
          List(0, 0, 1)
       )

    scala特有的构造办法如下:

    // 字符串列表
    val site = "Runoob" :: ("Google" :: ("Baidu" :: Nil))
    
    // 整型列表
    val nums = 1 :: (2 :: (3 :: (4 :: Nil)))
    
    // 空列表
    val empty = Nil
    
    // 二维列表
    val dim = (1 :: (0 :: (0 :: Nil))) ::
              (0 :: (1 :: (0 :: Nil))) ::
              (0 :: (0 :: (1 :: Nil))) :: Nil

    连接列表的操作

    你可以使用 ::: 运算符或 List.:::() 方法或 List.concat() 方法来连接两个或多个列表。实例如下:

    object Test {
       def main(args: Array[String]) {
          val site1 = "Runoob" :: ("Google" :: ("Baidu" :: Nil))
          val site2 = "Facebook" :: ("Taobao" :: Nil)
    
          // 使用 ::: 运算符
          var fruit = site1 ::: site2
          println( "site1 ::: site2 : " + fruit )
          
          // 使用 List.:::() 方法
          fruit = site1.:::(site2)
          println( "site1.:::(site2) : " + fruit )
    
          // 使用 concat 方法
          fruit = List.concat(site1, site2)
          println( "List.concat(site1, site2) : " + fruit  )
          
    
       }
    }

    集合(Set)

    可变集合和不可变集合。 虽然可变Set和不可变Set都有添加或删除元素的操作,但是有一个非常大的差别。对不可变Set进行操作,会产生一个新的set,原来的set并没有改变,这与List一样。 而对可变Set进行操作,改变的是该Set本身,与ListBuffer类似。

    import scala.collection.mutable.Set // 可以在任何地方引入 可变集合
    
    val mutableSet = Set(1,2,3)
    println(mutableSet.getClass.getName) // scala.collection.mutable.HashSet
    
    mutableSet.add(4)
    mutableSet.remove(1)
    mutableSet += 5
    mutableSet -= 2
    
    println(mutableSet) // Set(5, 3, 4)
    
    val another = mutableSet.toSet
    println(another.getClass.getName) // scala.collection.immutable.Set

    你可以使用 ++ 运算符或 Set.++() 方法来连接两个集合。如果元素有重复的就会移除重复的元素。实例如下:

    object Test {
       def main(args: Array[String]) {
          val site1 = Set("Runoob", "Google", "Baidu")
          val site2 = Set("Faceboook", "Taobao")
    
          // ++ 作为运算符使用
          var site = site1 ++ site2
          println( "site1 ++ site2 : " + site )
    
          //  ++ 作为方法使用
          site = site1.++(site2)
          println( "site1.++(site2) : " + site )
       }
    }

    映射(Map)

    默认情况下 Scala 使用不可变 Map。如果你需要使用可变集合,你需要显式的引入 import scala.collection.mutable.Map 类

    // 空哈希表,键为字符串,值为整型
    var A:Map[Char,Int] = Map()
    
    // Map 键值对演示
    val colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF")

    注意,Map的get方法返回的对象是一个Option[String],Option表示可能为None,比如key值不存在的情况,如果不为None则是Some(value)。

    Scala元组(Tuple)

    元组是每个元素类型可以不一样的List,最大的size是22。

    val t = (1, 3.14, "Fred")  
    val t = new Tuple3(1, 3.14, "Fred")//3是元组中元素的个数

    我们可以使用 t._1 访问第一个元素, t._2 访问第二个元素,如下所示:

    object Test {
       def main(args: Array[String]) {
          val t = (4,3,2,1)
    
          val sum = t._1 + t._2 + t._3 + t._4
    
          println( "元素之和为: "  + sum )
       }
    }

    类(class)

    scala的类和对象与java的类和对象基本上一样。

    类定义方法如下:

    class Point(xc: Int, yc: Int) {
       var x: Int = xc
       var y: Int = yc
    
       def move(dx: Int, dy: Int) {
          x = x + dx
          y = y + dy
          println ("x 的坐标点: " + x);
          println ("y 的坐标点: " + y);
       }
    }

    对象的定义方法是用object关键字,和java以class名.java 命名文件不同,scala是以类名.scala命名文件。

    接口(trait)

    trait关键字很像java的interface,但是它能够定义某个方法的实现。

    trait Equal {
      def isEqual(x: Any): Boolean
      def isNotEqual(x: Any): Boolean = !isEqual(x)
    }

    和java一样,scala只能继承一个父类,但如果是trait就可以继承多个,继承的关键字是extends

    模式匹配

    scala的 x match{case:...} 对应java中的switch(x){case:...}

    捕获异常

    scala的异常捕获和java大致一致,只是在catch的时候使用了模式匹配的思想。

    import java.io.FileReader
    import java.io.FileNotFoundException
    import java.io.IOException
    
    object Test {
       def main(args: Array[String]) {
          try {
             val f = new FileReader("input.txt")
          } catch {
             case ex: FileNotFoundException => {
                println("Missing file exception")
             }
             case ex: IOException => {
                println("IO Exception")
             }
          } finally {
             println("Exiting finally...")
          }
       }
    }

    提取器:apply和unapply

    提取器是从传递给它的对象中提取出构造该对象的参数。感觉这个玩意很鸡肋。

    object Test {
       def main(args: Array[String]) {
          
          //下面调用apply
          val x = Test(5)
          println(x)
    
          x match
          {
             //下面unapply 被调用
             case Test(num) => println(x + " 是 " + num + " 的两倍!")
             case _ => println("无法计算")
          }
    
       }
       def apply(x: Int) = x*2
       def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
    }

    文件IO

    scala写文件操作直接用的是java的io,读操作有自己的,总体来讲比java简单。

    import java.io._
    
    object Test {
       def main(args: Array[String]) {
          val writer = new PrintWriter(new File("test.txt" ))
    
          writer.write("菜鸟教程")
          writer.close()
       }
    }

    从屏幕读输入

    import scala.io._
    object Test {
       def main(args: Array[String]) {
          print("请输入菜鸟教程官网 : " )
    //2.11版本后。Console.readLine已废弃
          val line = StdIn.readLine()
    
          println("谢谢,你输入的是: " + line)
       }
    }

    从文件中读内容

    import scala.io.Source
    
    object Test {
       def main(args: Array[String]) {
          println("文件内容为:" )
    
          Source.fromFile("test.txt" ).foreach{ 
             print 
          }
       }
    }
  • 相关阅读:
    .NET 去除一段文本中的HTML标记
    C#实现控件拖动窗口
    使用window.showModalDialog弹出窗口返回值(兼容IE、FF、chrome)
    IE浏览器报错出现stack overflow at line 0的解决办法
    用Python作GIS:原料篇
    winform 自定义控件:半透明Loading控件
    WPF 跟随鼠标动画 by wgscd
    C# 多线程 HTTP request
    VS2015 安装XAN
    C# 用QQ企业邮箱发邮件
  • 原文地址:https://www.cnblogs.com/arli/p/9335679.html
Copyright © 2020-2023  润新知