zoukankan      html  css  js  c++  java
  • Spark记录-scala快速入门

    1.hello world程序

    object HelloWorld { 
        def main(args: Array[String]) { 
            println("Hello,World!") 
        } 
    } 
    

    注意

    语句末尾的分号通常是可选的。

    语句末尾的分号通常是可选的。

    分号是表达式分隔符,它们是推断的。

    Scala将行的结尾视为表达式的结尾,除非它可以推断表达式继续到下一行。

    Scala程序处理从主方法开始,这是每个Scala程序的一个强制性部分。

    主要方法未标记为静态。

    主要方法是对自动实例化的单例对象的实例方法。

    没有返回类型。实际上有Unit,这是类似于void,但它是由编译器推断。

    我们可以通过在参数后面加一个冒号和类型来显式地指定返回类型:

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

    Scala使用def关键字告诉编译器这是一个方法。

    在Scala中没有访问级别修改器。

    Scala未指定公用修饰符,因为默认访问级别为public。

    Scala变量

    在Scala中,有三种方法可以定义变量:val,var和延迟 val。

    Scala允许您在声明它时决定变量是否是不可变的(只读)

    val

    使用关键字val声明不可变变量。

    这意味着它是一个不能更改的变量。

    var

    现在让我们声明一个可变变量。

    一个可变变量用关键字var来声明:

    延迟val

    延迟val变量计算一次,第一次访问变量。只有vals可以是惰性变量。

    Scala 代码块

    方法和变量定义可以是如下的单行:

    def meth() = "Hello World"
    

    方法和变量也可以在用大括号{}表示的代码块中定义。

    代码块可以嵌套。

    代码块的结果是在代码块中计算的最后一行,如以下示例所示。

    object Main {
        def meth1():String = {"hi"}
        def meth2():String = {
            val d = new java.util.Date()
            d.toString()
        }
    
      def main(args: Array[String]) {
        println(meth1 )
        println(meth2 )
      }
    }
    

    变量定义也可以是代码块。

    val x3:String= {
        val d = new java.util.Date()
        d.toString()
    }

    Scala 注释

    Scala注释很像Java和C ++注释。

    多行注释以/*开头,以*/结束。

    /*
        This is a multiline comment:
    */
    

    单行注释用//开头,并继续到行尾:

    // This is a single line comment
    

    在Scala中,我们可以嵌套多行注释:

    /*
    This is an outer comment
    /* And this comment
    is nested
    */
    Outer comment
    */

    Scala 布尔类型

    val x = !false 

    Scala字符类型

    字符常量用单引号编写,区别于使用双引号写的字符串常量。

    Scala字符串

    Scala的String构建在Java的String上,并向Java的String添加了字符串插值等附加功能。

    字符串插值

    字符串插值是一种将字符串中的值与变量组合的机制。

    Scala中的插值符号是在字符串的第一个双引号之前添加的s前缀。

    然后可以使用美元符号运算符$引用变量。

    以下代码说明了字符串插值的用法。

    object Main {
      def main(args: Array[String]) {
          val bookTitle = "Scala" // creating a String 
          // String interpolation 
          println(s"Book Title is ${ bookTitle}" );
      }
    }

    Scala数字类型

    Scala中的数字数据类型构成了Float和Double类型以及诸如Byte,Short,Int,Long和Char等整数数据类型。

    下表显示Scala的数值数据类型。

    数据类型描述
    Byte 从-128到127范围内的整数
    Short 从-32768到32767范围内的整数
    Int 从-2147483648到2147483647范围内的整数
    Long 从-9223372036854775808到9223372036854775807范围内的整数
    Float 最大正有限浮点是3.4028235 * 1038,最小正有限非零浮点是1.40 * 10-45
    Double 最大正有限双是1.7976931348623157 * 10308,最小正有限非零双是4.9 * 10-324

    例子

    Scala可以按顺序自动将数字从一种类型转换为另一种类型。

    Byte . Short . Int . Long . Float . Double. 
    

    其中字节类型是最低的,并且可以转换为任何其他类型,如以下示例所示:

    val x: Byte = 30 
    

    我们可以将x赋值为Short类型,如下例所示:

    val y: Short = x 
    

    同样,我们可以将x赋值为Int,Long,Float,Double,Scala会自动转换数字,如下例所示:

    val z: Double = y 
    

    Scala不允许以前面提到的顺序自动转换。

    Scala常量值

    整数常量

    整数常量可以用十进制,十六进制或八进制表示。

    详细总结在下表中。

    类型格式例子
    Decimal 0或非零数字后跟零或多个数字(0-9) 0, 1, 321
    Hexadecimal 0x后跟一个或多个十六进制数字(0-9,A-F,a-f) 0xFF, 0x1a3b
    Octal 0后跟一个或多个八进制数字(0-7)a 013, 077

    截至Scala 2.10,一个八进制常量已被弃用。

    您可以通过在常量前添加一个-号来表示负数。

    对于长文本,需要在文本末尾附加Ll字符,除非将值分配给声明为Long的变量。 

    否则,推断Int。

    整数字符串的有效值受要为其分配值的变量的类型的限制。

    下表定义了包含的限制。

    目标类型最低(含)最大(包括)
    Long -263 263
    Int -231 231 - 1
    Short -215 215
    Char 0 216
    Byte -27 2- 1

    如果指定的整数常量数超出这些范围,则会发生编译时错误。

    浮点常量

    浮点常量是带有可选减号,零个或多个数字,后跟句点.,后跟一个或多个数字的表达式。

    对于Float常量,在文字末尾附加Ff字符。否则,假定为Double。

    我们可以选择为D加上Dd

    浮点常量可以用或不用指数表示。

    指数部分的格式为e或E,后跟可选的+或 - ,后跟一个或多个数字。

    这里有一些浮点常量的例子。 Double被推断除非声明的变量是Float或使用f或F后缀:

         .14 
         3.14 
         3.14f 
         3.14F 
         3.14d 
         3.14D 
         3e5 
         3E5 
         3.14e+5 
         3.14e-5 
         3.14e-5 
         3.14e-5f 
         3.14e-5F 
         3.14e-5d 
         3.14e-5D 
    

    布尔常量

    布尔常量是truefalse

    它们被分配到的变量的类型将被推断为布尔值:

    object Main {
      def main(args: Array[String]) {
         val b1 = true 
         val b2 = false 
         
         println(b1);
         println(b2);
      }    
    }
    

    字符常量

    字符常量是可打印的Unicode字符或转义序列,写在单引号之间。

    Unicode值介于0和255之间的字符可以由八进制转义表示,即反斜杠()后跟最多三个八进制字符的序列。

    这里有些例子:

    "A" 
    "u0041"  // "A" in Unicode 
    "
    " 
    "12"    // "
    " in octal 
    "	" 
    

    有效的转义序列如下表所示。

    序列含义
     退格(BS)
    水平制表(HT)
    换行(LT)
    f 换页(FF)
    回车(CR)...
    " 双引号(“)
    " 单引号(“)
    \ 反斜杠()

    字符串常量

    字符串常量是用双引号或三重双引号括起来的字符序列,即“”“...”“”。

    对于双引号中的字符串字符,允许的字符与字符常量相同。

    要在字符串中包含双引号字符,必须使用字符“转义"。

    这里有些例子:

    "This is a
    test" 
    "He said, "SQL is for database!"" 
    "First	Second" 
    

    由双引号的三元组界定的字符串常量称为多行字符串常量。

    这些字符串可以覆盖几行。换行符将是字符串的一部分。它们可以包括任何字符,包括一个或两个双引号在一起,但不能三个在一起。

    它们对于不具有有效Unicode或转义序列的字符的字符串非常有用。

    这里有三个示例字符串:

    """This is a 
    test""" 
    """He said, "SQL is for database!" """ 
    """First line
     
    Second line	 
    
    Fourth line""" 
    

    在代码中使用多行字符串时,要使用String.stripMargin缩进子字符串以进行正确的代码格式化。

    它删除子字符串中的所有空格,直到并包括垂直条|的第一次出现。

    要添加空格缩进,请将空格放在|后面。

    考虑这个例子:

    object Main {
      def main(args: Array[String]) {
         println(hello("This is a test") );
         
      }    
      def hello(name: String) = s"""Welcome! 
           Hello, $name! 
           * (Star!!) 
           |Hi. 
           |    whitespace.""" .stripMargin   
    }
    

    要使用不同于|的前导字符,请使用带有Char(字符)参数的stripMargin的重载版本。

    如果整个字符串都有要删除的前缀或后缀,则有相应的前缀和stripSuffix方法。

    object Main {
      def main(args: Array[String]) {
         println(goodbye("www.w3cschool.cn"));
         
      }    
      def goodbye(name: String) = 
           s"""xxxGoodbye, ${name}yyy 
           xxxCome again!yyy""" .stripPrefix("xxx").stripSuffix("yyy") 
    }
    

    符号常量

    Scala有符号类型,它们是内部连接的字符串,意味着具有相同“名称”的两个符号实际上是指内存中的同一个对象。

    符号常量是单引号',后跟一个或多个数字,字母或下划线(“_”),但第一个字符不能是数字。

    函数常量

    (i:Int,s:String)=> s + i 是Function2类型的函数文本[Int,String,String](返回String)。

    你甚至可以使用常量语法作为类型声明。

    以下声明是等效的:

    val f1: (Int,String) => String       = (i, s) => s+i 
    val f2: Function2[Int,String,String] = (i, s) => s+i 
    

    元组常量

    Scala库包括用于将N个项分组的TupleN类(例如,Tuple2),以及括号内的项的逗号分隔列表的文字语法。

    对于1到22之间的N,有单独的TupleN类。

    例如,val tup =(“Hi”,2014)定义了一个Tuple2实例,其中第一个元素推断String,第二个元素Int推断。

    Tuple实例是不可变的,第一类值,因此您可以将它们分配给变量,将它们作为值传递,并从方法中返回。

    我们还可以使用常量语法为Tuple类型声明:

    val t1: (Int,String)       = (1, "two") 
    val t2: Tuple2[Int,String] = (1, "two") 
    

    以下示例演示使用元组:

    object Main {
      def main(args: Array[String]) {
         val t = ("Hello", 1, 2.3)
         println( "Print the whole tuple: " + t )
         println( "Print the first item:  " + t._1 )
         println( "Print the second item: " + t._2 )
         println( "Print the third item:  " + t._3 )
    
         val (t1, t2, t3) = ("World",  "!", 0x22)
         println( t1 + ", " + t2 + ", " + t3 )
    
         val (t4, t5, t6) = Tuple3("World",  "!", 0x22)
         println( t4 + ", " + t5 + ", " + t6 )
      }
    }
    

    表达式t._n从元组t中检索第n个项,从一个开始,不是零,遵循历史约定。

    有几种方法来定义两元素元组,有时称为一对。

    我们可以在两个值之间使用“箭头运算符”,以及在元组相关类上使用特殊的工厂方法:

    (1, "one") 
    1 -> "one" 
    Tuple2(1, "one") 

    Scala Nothing和Null类型

    Null是所有引用类型的子类型。它是所有AnyRef类型的子类型,为关键字null提供类型。

    Scala没有null关键字。

    例如,不可能为scala.Int类型的变量分配null。

    对于影响程序流程的操作,没有任何提供兼容的返回类型。

    Nothing的用法之一是它发出异常终止的信号。

    任何时候,如果你想使用null,请改用Option

    Scala选项

    Option允许我们在没有null“hack”的情况下显式地表达空值。

    Option是一个抽象类,它的两个具体子类是Some,当我们有一个值,而None,当我们没有。

    例子

    您可以在以下示例中查看选项,一些和无操作,其中我们在美国创建州首府地图:

    object Main {
      def main(args: Array[String]) {
         val stateCapitals = Map( 
           "Alabama" -> "Montgomery", 
           "Alaska"  -> "Juneau", 
           "Wyoming" -> "Cheyenne") 
    
         println( "Get the capitals wrapped in Options:" ) 
         println( "Alabama: " + stateCapitals.get("Alabama") ) 
         println( "Wyoming: " + stateCapitals.get("Wyoming") ) 
         println( "Unknown: " + stateCapitals.get("Unknown") ) 
    
         println( "Get the capitals themselves out of the Options:" ) 
         println( "Alabama: " + stateCapitals.get("Alabama").get ) 
         println( "Wyoming: " + stateCapitals.get("Wyoming").getOrElse("Oops!") ) 
         println( "Unknown: " + stateCapitals.get("Unknown").getOrElse("Oops2!") ) 
    
      }
    }

    注意

    Map.get方法返回一个Option [T],在这种情况下T是String。

    通过返回一个选项,我们不能“忘记”我们必须验证返回的东西。

    如果OptionSome,则Some.get返回值。

    如果Option实际上是None,那么None.get将抛出一个NoSuchElementException异常。

    在最后两个println语句中的getOrElse返回Option中的值,如果它是一个Some实例,或者返回传递给getOrElse的参数,如果它是一个None实例。

    getOrElse参数作为默认返回值。

    Scala范围

    有些代码需要从一些开始到结束创建一个数字序列。一个Range常量量是我们需要的。

    范围可以通过它们的开始,结束和步进值来定义。

    要在Scala中创建范围,请使用预定义的方法,如以下代码所示:

    object Main {
      def main(args: Array[String]) {
        println(1 to 5  )
      }
    }
    

    我们还可以使用预定义的方法创建一个具有上限(不包括其上限)的范围,直到如下代码所示。

    object Main {
      def main(args: Array[String]) {
        println(1 until 5 )
      }
    }
    

    对于1到5,创建范围(1,2,3,4,5),但对于1到5,创建具有上限独占范围(1,2,3,4)的范围。

    我们还可以使用预定义的方法创建一个带有步进值的范围,如下面的代码所示。

    object Main {
      def main(args: Array[String]) {
        println(1 to 20 by 4  )
      }
    }

    例子

    以下示例显示如何为支持它们的类型创建范围:Int,Long,Float,Double,Char,BigInt和BigDecimal。

    object Main {
      def main(args: Array[String]) {
         var v = 1 to 10        // Int range inclusive, interval of 1, (1 to  10) 
         println(v)
         
         v = 1 until 10        // Int range exclusive, interval of 1, (1 to 9) 
         println(v)
    
         val v1 = 1 to 10 by 3           // Int range inclusive, every third. 
         println(v1)
         
         val v2 = 10 to 1 by -3          // Int range inclusive, every third, counting down. 
         println(v2)
    
         val v3 = 1L to 10L by 3         // Long 
         println(v3)
         
         
         val v4 = 1.1f to 10.3f by 3.1f  // Float with an interval != 1 
         println(v4)
    
         val v5 = 1.1f to 10.3f by 0.5f  // Float with an interval < 1 
         println(v5)
    
         val v6 = 1.1 to 10.3 by 3.1     // Double 
         println(v6)
    
         val v7 = "a" to "g " by 3         // Char 
         println(v7)
    
         val v8 = BigInt(1) to BigInt(10) by 3 
         println(v8)
         
         val v9 = BigDecimal(1.1) to BigDecimal(10.3) by 3.1 
         println(v9)
      }
    }
    

    注意

    您可以创建包含或独占上限的范围,并且您可以指定不等于1的间隔:

    Scala元组

    元组是具有相同或不同类型的两个或更多个值的有序容器。

    然而,与列表和数组不同,没有办法迭代元组中的元素。

    它的目的只是作为一个多个值的容器。

    元组在需要组合离散元素并提供结构化数据的通用方法时非常有用。

    我们可以通过两种方式创建一个元组:

    • 通过用逗号分隔的值写入值,并用一对括号括起来
    • 通过使用关系运算符->

    例子

    以下代码显示了一个包含Int,一个布尔值和一个String的元组,使用前一个方法。

    val tuple = (1, false, "Scala")
    

    以下代码显示了使用关系运算符创建的元组:

    val tuple2 ="title" -> "Beginning Scala"
    

    元组的单个元素可以通过其索引访问,其中第一个元素具有索引1。

    以下代码显示了访问元组的第三个元素。

    val tuple = (1, false, "Scala")
    val third = tuple._3

    Scala单元类型

    单元类型用于定义不返回数据的函数。它类似于Java中的void关键字。

    例子

    以下代码定义了具有单元类型的主方法。

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

    单元常量是一对空圆括号, ()。

    附录

    import org.apache.spark.SparkConf;
    import org.apache.spark.SparkContext;
    //定义一个类Person(属性,方法)
    class Person(val name: String, var age: Int)
    object base {
      //定义一个无返回值的方法
      def func(s:String):Unit={
        println(s)
      }
      def meth() = "Hello World" //单行方法代码块
      def meth1():String = {"hi"} //返回值为String的方法代码块
      def meth2():String = {      //具体的函数体实现(代码块)
        val d = new java.util.Date()
        d.toString()
      }
      //删除前缀和后缀
      def goodbye(name: String) =
        s"""xxxGoodbye, ${name}yyy
           xxxCome again!yyy""" .stripPrefix("xxx").stripSuffix("yyy")
      //主方法:Unit相当于void,无返回值类型
      def main(args: Array[String]): Unit = {
        //System.setProperty("hadoop.home.dir", "D:\hadoop");//设置hadoop环境
        //val conf = new SparkConf().setAppName("Base").setMaster("spark://192.168.66.66:7077");//加载spark远程作业调度
        //val spark=new SparkContext(conf);//声明一个sparkContext上下文
        val data = Array(1, 2, 3, 4, 5); //定义一个不可变数组
        func("hello");//调用方法
        println(data(1))//输出单个数组元素
        //遍历输出data数组
        for (i<-data)
        {
          println(i)
        }
        //spark.stop();
        for(i<- 1 to 10){
          println(i)
        }
        for {
          i <- 1 to 10
          j <- 1 to 10
        }
          println(i* j)
        val p = new Person("Dean Wampler", 29) //声明一个类对象
        println(p.name) //调用并输出类属性
        println(p.age )
        p.age = 30
        println(p.age )
        println(meth+"
    "+meth1()+"
    "+meth2())//函数调用无参数不需要带()
        /*定义一个不可变且返回值为String的代码块*/
        val x3:String= {
          val d = new java.util.Date()
          d.toString()
        }
        println(x3)
        val x = !false  //布尔类型
        var xf=true //布尔型常量
        val y='1'  //单引号的字符常量
        val z="scala" //双引号的字符串常量
        val zx:String="spark"
        println(xf+""+x+"-"+y+s"-${z}"+"-"+zx) //s"-${z}"字符串插值
        val xx: Byte = 30  //数字类型Byte . Short . Int . Long . Float . Double.
        val yy: Short = xx
        val zz: Double = yy
        println(xx+"-"+yy+"-"+zz)
        println(goodbye("www.w3cschool.cn"));
        //函数常量定义
        val f1: (Int,String) => String       = (i, s) => s+i //返回值为String
        val f2: Function2[Int,String,String] = (i, s) => s+i //前两个为参数,后一个为返回值
        println(f1(1,"name")+"-"+f2(1,"siat"))
        //元组常量
        //val t1: (Int,String)       = (1, "two")
        //val t2: Tuple2[Int,String] = (1, "two")
        val t = ("Hello", 1, 2.3) //定义一个元组
        println( "Print the whole tuple: " + t )   //输出整个元组
        println( "Print the first item:  " + t._1 ) //输出第一个元组元素
        println( "Print the second item: " + t._2 ) //输出第二个元组元素
        println( "Print the third item:  " + t._3 ) //输出第三个元组元素
       //定义三个元组,每个元组存储一个元素
        val (t1, t2, t3) = ("World",  "!", 0x22)
        println( t1 + ", " + t2 + ", " + t3 )
        val (t4, t5, t6) = Tuple3("World",  "!", 0x22)
        println( t4 + ", " + t5 + ", " + t6 )
        //Scala没有null关键字
        //范围Range
        println(1 to 5  ) //包括上限1,2,3,4,5
        println(1 until 5 ) //不包括上限1,2,3,4
        println(1 to 20 by 4  ) //从1到20每次进四个值包括下限1
        val v2 = 10 to 1 by -3   //Int
        val v3 = 1L to 10L by 3  //Long
        val v4 = 1.1f to 10.3f by 3.1f //Float
        val v5 = 1.1f to 10.3f by 0.5f
        val v6 = 1.1 to 10.3 by 3.1 //Double
        val v7 = 'a' to 'g' by 3   //Char
        val v8 = BigInt(1) to BigInt(10) by 3
        val v9 = BigDecimal(1.1) to BigDecimal(10.3) by 3.1
        println(v2+"-"+v3+"-"+v4+""+v5+""+v6+""+v7+""+v8+""+v9)
        val tuple = (1, false, "Scala")
        val tuple2 ="title" -> "Beginning Scala"
        val third = tuple._3
        println(tuple._2+"-"+tuple2._1+"-"+third)
        //Unit单元类型用于定义不返回数据的函数。它类似于Java中的void关键字。
      }
    }
  • 相关阅读:
    git命令无法自动补全(sles11.3)
    linux下安装svn出现configure: error: We require OpenSSL; try --with-openssl
    Linux系统下升级Python版本步骤(suse系统)
    git commit --amend
    关于device tree中的interrupts选项
    BufferedInputStream
    FileInputStream
    FileOutputStream
    泛型上下限
    泛型接口
  • 原文地址:https://www.cnblogs.com/xinfang520/p/7809030.html
Copyright © 2011-2022 走看看