加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala基础

发布时间:2020-12-16 09:18:53 所属栏目:安全 来源:网络整理
导读:Scala基础 1、介绍 Scala是spark和kafka采用的编程语言,本质上是对java语言进行脚本化处理,使得开发效率更高。Scala的代码编写起来非常简洁,但并不简单,主要是很多语法比较诡异,对于刚刚接触到scala的人员来讲,往往有些摸不到头脑。 2、scala使用 打开

Scala基础

1、介绍

Scala是spark和kafka采用的编程语言,本质上是对java语言进行脚本化处理,使得开发效率更高。Scala的代码编写起来非常简洁,但并不简单,主要是很多语法比较诡异,对于刚刚接触到scala的人员来讲,往往有些摸不到头脑。

2、scala使用

打开scala的shell命令行窗口,输入1 + 1,可以直接进行求值运算。scala shell采用REPL方式进行交互,即read->evalute->print->loop。进入如下环境,运行效果如下图所示:

cmd>scala.bat
scala> 1 + 1

2.1 查看帮助

$scala>:help

2.2 退出

$scala>:quit

2.3 常量和变量

scala的量分为常量和变量,var是变量,可以重新赋值,val是常量,不可以重新复制。

// 变量
val x =10
// 错误,不能重新赋值
x = 20

var x = 10
// 正确
x = 20

2.4 类型推断与自动补全

val x = 100
val x:Int = 100
// tab键自动提示
x.<tab>

2.5 定义函数

递归函数必须显式定义函数,因为无法进行类型推荐。

// 参数必须定义类型,返回值可以不写,自动推断出来
def add(a:Int,b:Int) = {
    a + b
}

// 显式定义返回值类型
def add(a:Int,b:Int):Int = {
    a + b
}

// 递归实现阶乘
def frac(n:Int):Int = {
    if(n == 1) 1 else n * frac(n - 1)
}

2.6 to和until

to和until都可以定义Range集合,to是闭区间,until是半闭半开区间。

// 1 .. 10
1 to 10
1.to(10)

// 1 .. 9
1 until 10
1.until(10)

2.7 字符串

// 取交集,lo
"hello".intersect("world")

2.8 BigInt

var b = BigInt(999999999)
b * b * b * b

2.9 ++/--

scala没有++或--操作,可以使用+=或-=,这些也都是方法。

var x = 1 
// x ++ 
x += 1
x.+=(1)

// x --
x -=1 
x.-=(1)

2.10 sqrt与pow

开方函数和幂函数都在math包下,因此需要导入才能使用:

import scala.math._
// 4开方=2.0
sqrt(4)
// 2的立方=8
pow(2,3)

2.11 表达式的值

scala的每个表达式或者代码块都有值,最后一行语句的值就是表达式的值。

val x = 2
// y = 1
val y = if (x < 1) -1 else 1

2.12 apply方法

scala为很多类提供了apply方法,可以方便进行各种对象的创建和元素的获取,apply方法名成通常可以省略,因此会让方法调用显得有些奇怪。

// 省略apply方法名
val arr = Array[Int](1,2,3)
val arr = Array[Int].apply(1,3) ;

// 省略了apply方法
"hello"(0)
"hello".apply(0)

2.13 粘贴模式

在scala shell可以使用粘贴模式来贴入大量代码:

# 进入粘贴模式的命令
$scala>:paste

# ctrl + d退出粘贴模式

2.14 读取控制台输入

// 字符串为控制台提示符
val name = readLine("请输入用户名:") ;
println(name) ;

运行结果如图:

2.15 循环

2.15.1 while

while循环同java相似,都是用boolean类型表示进行控制。

  • 输出1~10

    var n = 1
    while(n < 11){
      println(n)
        n += 1
    }
  • 输出99表格

    var row = 1
    while( row <= 9 ){
      var col = 1 
        while( col <= 9){
          printf("%dx%d=%dt",col,row,(col * row))
        }
        println()
    }
2.15.2 for
  • 输出1~10

    for(i <- 1 to 10){
      println(i)
    }
  • 输出99表格

    for(r <- 1 to 10){
        for(c <- 1 to r){
            printf("%dx%d=%dt",c,r,(c * r))
        }
        println()
    }

    运行结果如下:

  • 带守卫条件的循环

    for(i <- 1 to 3 ; j <- 4 to 6 if j != 5){
      printf("%d : %drn",i,j )
    }

    如果j不等5的条件下,和i进行组合计算:

2.16 break

scala没有break语句,需要导入特定的函数来执行:

// 导入break函数
import scala.util.control.Breaks.break

for(i <- 1 to 10){
  if(i % 3 == 0){
    break 
  }
}

2.17 yield产生新集合

// 每个元素 * 2,组成新集合
for(i <- 1 to 5) yield i * 2

执行结果如下:

2.18 函数

  • 定义函数

    // 递归函数必须显式定义返回值类型
    def fac(n:Int) : Int = {
      var result = 0 
        for(i <- (1 to n)){
          result *= i
        }
        //最后一条语句是返回值
        result
    }
  • 参数默认值和带名参数

    // 定义修饰串函数
    def decorate(prefix:String="{{{",str:String,suffix:String="}}}") = {
      prefix + str + suffix 
    }
    //调用函数
    decorate("<<<","hello",">>>")
    // 输出结果
    "<<<hello>>>"
    // 使用带名参数向特定参数传值
    decorate(str="world",suffix="}}}")
  • 变长参数

    变长参数等价于java中的可变参数,即参数的类型个数可以不固定。

    // 定义可变参数
    def add(x:Int*) = {
        var sum = 0 
        for(i <- x){
          sum += i 
        }
        sum
    }
    
    // 传递多个参数
    add(1,3)
    
    // 使用_*转换成数字序列
    add(1 to 10 :_*)
  • 过程

    scala中将不带“=”的函数称之为过程,本质上和函数没有区别。

    // 没有=号
    def sayHi() {
        println("hello world!")
    }

2.19 lazy

lazy是延迟计算,即表达式不会立即求值,而是使用lazy字样作为占位符,等真正用到的时候再进行计算。spark的广播变量中使用该中方式进行的实现。

// lazy变量,不会出错
lazy var x = 1 / 0

// 出错
x

2.20 定义数组

  • 一维数组

    # 定义一个一维数组,长度为5个元素。
    val arr = new Array[Int](5)
    
    # 定义一个一维数组,内部调用apply方法
    var arr = Array[Int](5)
    var arr = Array[Int](1,3,4,5)
  • 二维数组

    // 定义二维数组
    var arrr = new Array[Array[Int]](3)
    // 赋值
    arrr[0] = Array[Int](1,3)
    
    # 三行四列数组
    val arr = Array.ofDim[Int](3,4)
    # 第一行第二列为2
    arr(0)(1) = 2

2.21 ArrayBuffer

数组缓冲区是可变数组,位于scala.collection.mutable包下,使用时需要进行导入。scala使用符号定义的方法有一定规律性:

    当个符号的方法通常意味着操纵一个元素,如:

    val arr = ArrayBuffer[Int](1,3)
    arr.+(4)
  • ++

    两个以上符号命名的方法意味着操纵的是集合元素,如:

    arr.++(5 to 8)
  • +=

    带有“=”号的方法意味着对自身的修改,如:

    // 改变自身的内容
    arr.+=(4)
  • 常用方法

    buf.trimEnd(3)                // 删除最后的三个元素
    buf.insert(0,1,3)           // 在0位置插入1,3序列
    buf.toArray()             // 转换成数组
    buf.reverse()             // 倒序
    buf.sum()                 // 求和
    buf.max()                 // 最大值
    buf.mkString(",")         // 对元素拼接成串
    buf.mkString("{",","}") // 对元素拼接成串

2.22 java与scala集合互操作

java集合可以和scala进行相互无缝调用,需要导入隐式转换包才可以。代码如下:

/* 自动将scala buffer转换成java list */
val list:java.util.List[String] = new java.util.ArrayList[String]()
list.add("hello")
list.add("world")
def mybuf(buf:scala.collection.mutable.Buffer[String]) = println(buf.size())
import scala.collection.JavaConversions.asScalaBuffer
mybuf(list)

/* 自动将scala buffer转换成java list */
val buf = ArrayBuffer[String]("how","are","you")
def mylist(list:java.util.List[String]) = println(list.size())
import scala.collection.JavaConversions.bufferAsJavaList
mylist(buf)

3、map操作

val t = (1,"tomas",12)  // 元组
val t = (1,"tomas")       // 对偶,对偶是特殊的元组,只有两个元素。
val t = 1 -> "tomas"        // 对偶


val map = Map(1->"tom",2->"tomas",3->"tomasLee")    // 构造map
val map = Map((1,"tom"),(2,"tomas"),(3,"tomasLee"))     // 构造map

map(1)  // 指定key,访问value
map(2)  //

// 迭代key-value
for((k,v) <- map){
    println(k + " : " + v)
}

// 迭代key
for(k <- map.keys){
    ...
}

// 迭代values
for(v <- map.values){
    ...
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读