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 
"\n" 
"\012"    // "\n" in octal 
"\t" 

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

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

字符串常量

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

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

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

这里有些例子:

"This is a\ntest" 
"He said, \"SQL is for database!\"" 
"First\tSecond" 

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

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

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

这里有三个示例字符串:

"""This is a \ntest""" 
"""He said, "SQL is for database!" """ 
"""First line\n 
Second line\t 

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+"\n"+meth1()+"\n"+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关键字。
  }
}
posted @ 2017-11-09 13:57  信方  阅读(10578)  评论(0编辑  收藏  举报