Scala基础知识笔记1

 

上一篇文章介绍了如何下载scala, 因为在官网上点击下载按钮无法下载, 

下面介绍scala的基础语法:

 

1 scala和java的关系

 Scala是基于jvm的一门编程语言,Scala的代码最终会经过编译成字节码,交给java虚拟机来运行

Scala和java可以无缝互操作,Scala可以任意调用java代码、

 

2 Scala的解释器 repl 

scala的解释器会快速编译scala代码为字节码然后交给jvm来执行。

repl :  read 取值 ---> evaluation 求值  ----> print 打印 ----> loop 循环  

 

3 声明变量和常量和指定类型

声明变量使用 var  这个和 js类似

声明常量使用 val  声明常量赋值后  这个常量将不能再被改变值

定义中建议使用常量声明,类似于spark的大型复杂系统中,需要大量网络传输数据,如果使用var 可能会担心值被错误的更改,这个类似于java中使用final关键字来

提高系统健壮性一样。

 

eg:  var name:String = "zm"

       var name1, name2:String = "zm"

 

4 数据类型和操作符

基本数据类型: Byte、Char、Short、Int、Long、Float、Double、Boolean。  和java的包装类型一致,没有基本数据类型

操作符: 和java的操作符一致, 唯一区别是 ++ --没有,  比如 a++ 必须写成 a += 1

 

5 函数调用

调用函数如果不需要传递参数 那么 scala 允许省略掉括号。

 

6 块表达式:

 

指的就是{}中的值, 最后一个语句的值就是块表达式的返回值。

eg:

var a = 1;
var b = 2;
var c = 3;
var d = if(a < 10) { b = b + 1; c + 1 }
println(d)
结果是4 也就是将 c+1的结果返回给了d

 

 7 条件和循环案例:

/* if 案例
  val age = 34;
  if(age < 10) {
    println("you are child")
  }else{
    println("you are adult")
  }*/
  //  块表达式
/*  var a = 1;
  var b = 2;
  var c = 3;
  var d = if(a < 10) { b = b + 1; c + 1 }
  println(d)*/

  // while  和java使用规则一样
/*  var n = 10
  while(n>0) {
    println(n)
    n -= 1
  }*/

  // for循环   scala只有如下这种形式的for写法
  // 1 简易版的for
 // var n=10; for(i<- 1 to n) println(i)
  //for(c<-"hello world") println(c)

   // 跳出循环  scala没有类似java的break语句 但可使用 boolean变量 return或Breaks的break函数
/*  import scala.util.control.Breaks._
  breakable{
    var n=10;
    for(i<-1 to 10){
      if(i==3) {
        break;
      }
      println(i);
    }
  }*/

  // 多重for
/*  for(i<-1 to 9; j<-1 to 9){
    println(i*j +" " )
  }*/

 

8 定义函数:

定义函数的函数名、参数、函数体,返回值类型, 其中形参和返回值类型都使用 :类型 方式 , 如果函数有返回值 那么需要在形参定义完成后 在使用  = {函数体}

如果定义的函数名和函数体之间没有用 = 关联 那么默认返回值类型是Unit,并且定义的是一个过程而不是一个函数 过程通常用于不需要返回值的函数。

使用 def关键词定义, 注意 参数和函数体之间使用 = 来连接, 如果给默认参数赋初始值 需要在定义形参中里使用 = 赋值

  // 代码块中最后一行的返回值就是整个函数的返回值。与Java中不同,不是使用return返回值的。 不过使用 return 我试验了也没发现报错

  /*def sayHello(name:String):String ={
     "hello " + name
  }
  var name = sayHello("zm")
  println(name)*/
  /*def fab(n:Int):Int={
    if(n <=1)  return 1
    else  return 3
  }
  var result = fab(5)
  println(result)*/

   // 给默认参数赋初始值
/*  def sayHello(name:String, age:Int=32) = {
     println(name + "| " + age)
   }
  sayHello("zm",34)
  sayHello("zm")*/

 

9  函数可变参数 + 序列传递 + 递归函数写法

函数定义中 变长参数使用   形参定义后需要增加一个*表示可变参数

object ScalaExample {

  def main(args: Array[String]): Unit = {
   // println(sum(1,2,3))

    // 将已有序列直接调用变长参数函数,  需要使用特殊语法让scala解释器识别 ---》  :_*
    //var result = sum(1 to 5:_*)
    //println(result)
    println(sum2(1 to 5:_*))  // 1 to 5表示序列 序列传递给可变参数的函数

  }

  // 定义可变参数函数
  def sum(nums:Int*)= {
    var res = 0;
    for(num<-nums) {
      res += num
    }
    res
  }
// 定义递归函数
  def sum2(nums:Int*) :Int={
    if(nums.length==0) 0
    else nums.head + sum2(nums.tail:_*)
  }



}

 

 

 

 

10  过程  lazy值  异常 

 

1 定义函数时,如果函数体直接包裹在了花括号里面,而没有使用=连接,则函数的返回值类型就是Unit。这样的函数就被称之为过程。过程通常用于不需要返回值的函数。

  // 过程是函数的一个子集  不需要使用 = 和函数体关联   表示没有返回值的函数
  /*def sayHello(name:String){
    println("hello: " + name)
  }
  var result = sayHello("zm")
  println(result) // 结果是()*/

  // 如果将一个变量生命为lazy   //即使文件不存在,也不会报错,只有在第一个使用该变量时如果文件不存在才会报错,证明了表达式计算的lazy特性。
  // 这种特性对于特别耗时的计算操作特别有用,比如打开文件进行IO,进行网络IO等
  import scala.io.Source._
  lazy val lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString

  // 异常的写法和Java很类似  例子如下    注意  catch 里面的写法   _: XXException => dosomething
  try {
    throw new IllegalArgumentException("x should not be negative")
  } catch {
    case _: IllegalArgumentException => println("Illegal Argument!")
  } finally {
    print("release resources!")
  }

 

11 数组 和 遍历的集中方式

scala数组底层实际上是Java数组,比如scala的字符串数组在底层就是Java的String[] , 整数数组底层就是Java的Int[]

for遍历几个方式:  增强for循环   正常方式遍历   跳跃遍历   翻转遍历 , 定长变长数组定义和互换和变长数组增减元素写法

  // 定长数组  定义定长数组方式1
  var a = new Array[Int](3)
  a(0) = 2
  // 定义定长数组方式2
  var b = Array(1,2,3)

  // 定义变长数组
  import scala.collection.mutable.ArrayBuffer
  val b1 = new ArrayBuffer[Int]()
  // 使用+=操作符,可以添加一个元素,或者多个元素
  b1 += 1
  b1 += (2,3,4,5)
  // 使用++=操作符,可以添加其他集合中的所有元素
  b1 ++= Array(6,7,8,9,10)
 // for(c<-b1) println(c)
  // 删除尾部的几个元素
  b1.trimEnd(5)
 // for(c<-b1) println(c)
  // 添加元素
  // 在index为5的位置上插入数字6
  b1.insert(5,6) // 在index为5的位置上插入数字6
  b1.insert(6,7, 8, 9, 10)// 在index为6的位置上插入数字 7,8,9,10
  //for(c<-b1) println(c)  // 增强for的遍历
  //删除元素SW
  b1.remove(1)  // 移除掉index为1上的元素
  //for(c<-b1) println(c) // 1 3 4 5 6 7 8 9 10
  b1.remove(1,3) //移除掉index为1上包含index为1开始向后一致移除三个  1 6 7 8 9 10
  // for(c<-b1) println(c)
  //var d = b1.toArray // 变长数组转换为定长数组
  //var c = b.toBuffer // 定长数组转换为变长数组
  // 数组普通遍历
 // for(i<- 0 until b1.length) println(b1(i))
 // for(i<- 0 until (b1.length,2)) println(b1(i)) // 跳跃遍历  间隔两个 取第三个
  //for(i<- (0 until b1.length).reverse)  println(b1(i)) // 翻转遍历  间隔两个 取第三个
val a = Array(1,2,4,3,5)
val sum = a.sum // 求和
val max = a.max // 获取最大值

// 排序
scala.util.Sorting.quickSort(a)
print(a.mkString(",")) // 获取数组中所有元素内容指定间隔符间隔 1,2,3,4,5

// yield 根据条件选择构建数组
/*
对于for循环的每次迭代,yield都会生成一个将被记住的值。就像有一个你看不见的缓冲区,for循环的每一次迭代都会将另一个新的值添加到该缓冲区
当for循环结束运行时,它将返回所有已赋值的集合。返回的集合的类型与迭代产生的类型相同,因此Map会生成Map,List将生成List,等等。
另外请注意,最初的集合没有改变。for / yield构造根据您指定的算法创建一个新的集合。
* */
// var a = Array(1,2,3,4,5,6)
//var b = for(c<-a) yield c*2
// var b = for(c<-a if c%2==0) yield c*c // yield + for + if 组合筛选构建新数组

//var b = a.filter(_%2==0) // 2-4-6
// var b = a.filter(_%2==0).map(_*2) // 4-8-12 通过数组函数来 筛选和构建新数组
// println(b.mkString("-"))

var a = ArrayBuffer(1,2,3,4,5,-8,-3,11,-5,-9)
/* var foundFirstNegative = false
val keepIndexes = for (i <- 0 until a.length if !foundFirstNegative || a(i) >= 0) yield {
if (a(i) < 0) foundFirstNegative = true
i
}
for (i <- 0 until keepIndexes.length) { a(i) = a(keepIndexes(i)) }
a.trimEnd(a.length - keepIndexes.length)
println(a.mkString("-"))
*/
// 遍历数组里所有元素,当找到第一个负数时 设置flag位 同时标注每个元素如果是大于0下的数组索引位置
/* var firstNagivate = false
var indexFlag = for(i<- 0 until a.length if(!firstNagivate || a(i) > 0)) yield {
if(a(i) < 0) firstNagivate = true
i
}*/
//println(indexFlag.mkString("-"))
/* for(i<- 0 until( indexFlag.length)) { // 将找到元素位置的数据重写到 原来数组中
a(i) = a(indexFlag(i))
}
a.trimEnd(a.length - indexFlag.length) // 将原来数组中不需要的数据截取掉
println(a.mkString("-"))*/
/* println("数组长度为: " + indexFlag.length)
var newA = new Array[Int](indexFlag.length)
for(i<- 0 until( indexFlag.length)) { // 将找到元素位置的数据重写到 新数组中
// newA(i+1) = a(indexFlag(i))
println(i+ " | "+ a(indexFlag(i)))
newA(i) = a(indexFlag(i))
}*/
 

 

12 Map 和 Tuple

  //map 学习
  // 不可变map      ()
  val ages = Map("zm"->32,"liangliang"->31)
  //ages("zm") = 31    不可以赋值修改
  // 可变map
  val ages1 = scala.collection.mutable.Map("zm"->32,"liangliang"->31)
  //val ages2 = scala.collection.mutable.Map(("zm",32),("liangliang",31))  或者这种方式定义
  ages1("zm")=31 // 修改可变map的value值
  // 创建空的map
  //val ages2 = new mutable.HashMap[String,Int]
  //val result = ages1.getOrElse("zm",42);  // 获取map的key值
  //println(result)
  ages1 += ("yan"->34,"mei"->30 ) // 可变map增加元素
  //ages1 -= "yan" // 可变map删除元素
 // println(ages1.mkString(","))
/*  val ages4 = Map("zm"->32)   //  不可变map 增减元素是通过 + - 方式并构建一个新的map接受 可变map增减是通过 += -=方式但必须要构建新的map
  val ages5 = ages4 + ("liang"->30)
  //println(ages5.mkString(","))
  val ages6 = ages5 - "liang"
  println(ages6.mkString(","))*/
  // map的遍历
  //for((k,v)<-ages1) println(k+"," +v)
 // val ages6 = for((k,v)<-ages1) yield(v,k) // 使用 yield构建新的map
  //println(ages6.mkString(","))
  //for(k<-ages1.keySet) println(k)
  //for(v<-ages1.values) println(v)
  // 对map的key进行排序  看了下 只有immutable包下有这个排序的方法  返回给一个新的map
// val ages7 = scala.collection.immutable.SortedMap("liang"->31,"ping"->29,"ming"->32)
 // println(ages7.mkString(","))
 //val ages8 = new scala.collection.mutable.LinkedHashMap[String,Int] // 按照插入顺序存放k-v 否则map的k是没有顺序的
  //ages8("zm")=34

 // 元组  tuple 在spark中有大量的tuple的使用,是一种很灵活的数据结构
  val t = ("zm",32)
  //println(t._1)
  val names = Array("zm","ping")
  val age1s =  Array(34,30)
  val nameages = names.zip(age1s)  //  zip操作  替代了自定义javabean方式
  for ((name, age) <- nameages) println(name + ": " + age)

// tuple ,就是由()包起来,和数据库中一条记录概念类似 ,或者理解为 是一个特殊类型的数组,数组中存储的是不同类型的值,一个元组中最多能存22个元素
var firstTuple = ("str",1,0.5)
println(firstTuple._1) // 返回 str 字符串 注意使用时不要写成按照 数组方式获取值了 这不是数组


 

posted on 2018-12-22 15:59  ligongda2006  阅读(178)  评论(0编辑  收藏  举报