• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Scala 基础

武飞扬头像
风老魔
帮助1

1. Scala 安装

Scala 运行于Java平台(JVM,Java 虚拟机)上,并兼容现有的Java程序,Scala代码可以调用Java方法,访问Java字段,继承Java类和实现Java接口。在面向对象方面,Scala是一门非常纯粹的面向对象编程语言,也就是说,在Scala中,每个值都是对象,每个操作都是方法调用,有如下优点:

  • 强大并发性、支持函数式编程(简单),可更好支持分布式系统
  • 语法简洁,可提供优雅 API
  • 兼容 Java,运行速度快,可融合到 Hadoop 生态圈

Hello World

// 主函数名与文件名可不一致,区别于 Java
object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello World!")
  }
}

参考文章:IDEA中配置Scala开发编译环境

2. 基础

2.1 基本操作

  • 变量:双引号
  • 语句后面可以没有分号
  • 注释:///* */
  • 终端退出 scala shell 环境:scala> :quit

2.2 变量

两种类型变量:

  • 可变 var:声明后可再赋值
  • 不可变 val:声明时必须初始化值,一旦声明不能赋值

val 不可变变量

scala> val name = "rose"                   
name: String = rose                        
        
// 重新赋值报错
scala> name="lila"                         
<console>:12: error: reassignment to val   
       name="lila"                         
           ^          

// 显示指定数据类型
scala> val name:String = "lila"
name: String = lila

scala> val name:java.lang.String = "john"
name: String = john

scala> println(name)
john
学新通

注意:Scala 在声明变量时可不显示地指定变量类型,它可根据值反推数据类型,也可以显示指定变量类型!Scala 的数据类型由 import java.lang._ 包提供,每个程序会隐士地导入所有,所以可以不用再导入


var 可变变量

scala> var age = 19
age: Int = 19

scala> age = 18
age: Int = 18

2.3 基本数据类型

基本数据类型包括:Byte、Char、Short、Int、Long、Float、DoubleBoolean,这些数据类型每个都是一个 Scala 包,如:Intscala.Int

字面量

字面量包括整数字面量、浮点数字面量、布尔型字面量、字符字面量、字符串字面量、符号字面量、函数字面量和元组字面量:

scala> val a = 123		// 整数字面量
a: Int = 123

scala> var a = 1.23		// 浮点数字面量
a: Double = 1.23

scala> var a = true		// 布尔字面量
a: Boolean = true

scala> var a = "ABC"	// 字符串字面量
a: String = ABC

scala> var a = "A"		// 字符字面量
a: String = A

Scala 可对字面量直接调用方法,如:

// 整数字面量转换为字符串
scala> 8.toString()
res1: String = 8

// 获取两个字符串都有的字符
scala> "abc".intersect("bcd")
res2: String = bc

操作符

Scala 的支持的操作符包括:加( )、减(-) 、乘(*) 、除(/) 、余数(%)等,使用格式:

// 两者等价
a 操作符 b
(a). 操作符 (b)

示例:

// 实际内部调用的就是 (5). (3)
scala> 5   3		
res3: Int = 8

scala> (5). (3)
res4: Int = 8

// 递增、递减,区别于 Java 的     --
scala> var age = 18
age: Int = 18

scala> age -= 1

scala> age
res6: Int = 17

2.4 Range

Range 支持创建不同数据类型的数值序列,包括 Int、Long、Float、Double、Char、BigIntBigDecimal等,一般与 for 循环配合使用:

// 生成一个 1 到 5 的整数序列,包括 5,步长默认为 1
scala> 1 to 5
res7: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)

scala> 1.to(5)
res8: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)

// 生成一个 1 到 5 的整数序列,不包括 5
scala> 1 until 5
res9: scala.collection.immutable.Range = Range(1, 2, 3, 4)

// 指定步长
scala> 1 to 22 by 2
res10: scala.collection.immutable.Range = Range(1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21)

scala> 0.5f to 5.9f by 0.8f
res11: scala.collection.immutable.NumericRange[Float] = NumericRange(0.5, 1.3, 2.1, 2.8999999, 3.6999998, 4.5, 5.3)
学新通

2.5 控制台输入输出

scala> val name = "rose"	
name: String = rose

// 换行输出
scala> println(name)
rose

// 不换行输出
scala> print(name)
rose

scala> val age = 18
age: Int = 18

// 字符串格式化
scala> printf("My name's %s age: %d.", name, age)
My name's rose,age: 18.
学新通

控制台读写数据

读写方法:readInt、readDouble、readByte、readShort、readFloat、readLong、readChar、readBoolean、readLine,分别对应 9 中不同数据类型,前 8 种没参数,readLine 可不提供参数,也可以带一个字符串参数的提示:

这些方法都属于对象 scala.io.StdIn,使用前必须导入,在控制台输入数据不会显示(回车后才会显示):

scala> import io.StdIn._
import io.StdIn._

scala> var i = readInt()
i: Int = 54

scala> var f=readFloat()
f: Float = 52.2

scala> var b= readBoolean()
b: Boolean = true

scala> var info = readLine("please input your name: ")
please input your name: info: String = rose

scala> info
res15: String = rose
学新通

2.6 读写文件

写文件

scala> import java.io.PrintWriter
import java.io.PrintWriter

scala> val out = new PrintWriter("C:\\Users\\hj\\Desktop\\scala.txt")
out: java.io.PrintWriter = java.io.PrintWriter@34604b32

scala> for(i <- 1 to 5) out.println(i)

scala> out.close()

读文件

scala> import scala.io.Source
import scala.io.Source

scala> val inputFile = Source.fromFile("C:\\Users\\hj\\Desktop\\scala.txt")
inputFile: scala.io.BufferedSource = non-empty iterator

scala> val lines = inputFile.getLines
lines: Iterator[String] = non-empty iterator

scala> for (line <- lines) println(line)
1
2
3
4
5

scala> inputFile.close()
学新通

IDEA 中使用

import scala.io.Source
import java.io.PrintWriter


object ReadWriteFile {
  def main(args: Array[String]): Unit = {
    readFile()
    writeFile()
  }

  def readFile(): Unit = {
    val inputFile = Source.fromFile("C:\\\\Users\\\\hj\\\\Desktop\\\\scala.txt")
    val lines = inputFile.getLines()
    for (line <- lines) {
      println(line)
    }
    inputFile.close()
  }

  def writeFile(): Unit = {
    val out = new PrintWriter("C:\\\\Users\\\\hj\\\\Desktop\\\\scala.txt")
    for (i <- 1 to 10 by 2) {
      out.println(i)
    }
    out.close()
  }
}
学新通

2.7 异常处理

import java.io.{FileNotFoundException, FileReader, IOException}

object TryCatch {
  def main(args: Array[String]): Unit = {
    try {
      val f = new FileReader("input.txt")
    } catch {
      case ex: FileNotFoundException =>
        println("文件不存在!", ex)
      case ex: IOException =>
        println("IO 错误操作", ex)
    } finally {
      println("Exiting finally...")
    }
  }
}
学新通
(文件不存在!,java.io.FileNotFoundException: input.txt (系统找不到指定的文件。))
Exiting finally...

3. 控制结构

3.1 if 条件表达式

object LoopTest {
  def main(args: Array[String]): Unit = {
    val score = 99
    if (score > 80) {
      println("A")
    } else if (score < 80 && score > 70) {
      println("B")
    }else {
      println("C")
    }
  }

}

if 条件表达的值可赋值给变量

scala> val x = 8                                          
x: Int = 8                                                
                                                          
scala> val y = if (x>0) 1 else -1                         
y: Int = 1                                                

3.2 while 循环

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

  def test_while(): Unit = {
    var i = 15
    while (i <= 30) {
      i  = 1
    }
    println(i)

    var m = 10
    do {
      m  = 1
    } while (m < 31)
    println(m)
  }
}
学新通

3.3 for 循环

格式:

// 变量<-表达式 部分被称为生成器
for (变量<-表达式) 语句块
scala> for (i <- 1 to 6) println(i)                 
1                                                   
2                                                   
3                                                   
4                                                   
5                                                   
6                                                   
  
// 设置步长为 2
scala> for (i <- 1 to 6 by 2) println(i)            
1                                                   
3                                                   
5                                                   
        
// 设置守卫,满足条件才能返回
scala> for (i <- 1 to 6 by 3 if i%2==0) println(i)  
4                                                   
学新通

多生成器

类似于多个 for 循环

scala> for (i <- 1 to 3; j <- 2 to 5) println(i*j)
2
3
4
5
4
6
8
10
6
9
12
15

守卫:

scala> for (i <- 1 to 3 if i==2; j <- 2 to 5 if j==3) println(i*j)
6

for 推导式

通过 for 循环遍历一个或多个集合,对集合中的元素进行 推导,从而计算得到新的集合,用于后续处理:

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

  def test_for(): Unit ={
    var abc = for (i <- 1 to 5 if i%2==0) yield i

    for (a <- abc) {
      println(a)
    }
  }
}

abc 是变量,yield 会将结果存储到集合中,循环结束后将返回该集合:

2
4

4. 数据结构

常用数据结构:

  • 容器 Collection
  • 列表 LIst
  • 集合 Set
  • 映射 Map
  • 迭代器 Iterator
  • 数组 Array
  • 元组 Tuple

4.1 容器

Scala 有一套丰富的容器库,包括:列表、数组、集合、映射等,根据元素组织方式和操作方式,可分为:有序和无序、可变和不可变等不同容器类别,容器的三个类:

scala.collection、scala.collection.mutable、scala.collection.immutable

4.2 列表

列表是一种共享相同类型不可变的对象序列,一旦定义值不能改变,声明时必须初始化值:

// 因为是不可变集合,索引列表存在 scala.collection.immutable 中
scala> import scala.collection.immutable
import scala.collection.immutable

scala> var strList = List("A", "B", "C")
strList: List[String] = List(A, B, C)

// 获取第一个元素
scala> strList.head
res1: String = A

// 获取除第一个元素后的所有元素集合(新的列表)
scala> strList.tail
res2: List[String] = List(B, C)

构造列表

使用格式:

// 在已有列表前端增加元素
元素::列表
// 将元素 D 添加到新列表 a_list 中
scala> val a_list = "D"::strList
a_list: List[String] = List(D, A, B, C)

// 生成一个新的列表 a_list
scala> a_list
res3: List[String] = List(D, A, B, C)

// 原列表保持不变
scala> strList
res4: List[String] = List(A, B, C)

Nil 空列表对象

scala> val b = 1::2::3::Nil
b: List[Int] = List(1, 2, 3)

// 效果与  List(1, 2, 3) 等同

4.3 集合

集合的元素不重复,无序,以 哈希 方式来组织元素,包括:

  • 可变集合:scala.collection.mutable
  • 不可变集合:scala.collection.immutable,缺省情况下创建的是不可变集合,通常使用不可变集合

不可变集合

// 不能使用 val
scala> var set1 = Set("Hadoop", "Scala")
set1: scala.collection.immutable.Set[String] = Set(Hadoop, Scala)

scala> set1  = "Spark"

scala> set1
res6: scala.collection.immutable.Set[String] = Set(Hadoop, Scala, Spark)

scala> set1.contains("Scala")
res7: Boolean = true

可变集合

// 必须先引入 scala.collection.mutable.Set  
scala> import scala.collection.mutable.Set                  
import scala.collection.mutable.Set                         
                                                            
scala> val set2 = Set("A", "B")                             
set2: scala.collection.mutable.Set[String] = Set(B, A)      
                                                            
scala> set2  = "C"                                          
res8: set2.type = Set(B, C, A)                              

注意:对不可变集进行操作,会产生一个新的集合,原来的集合并不会发生变化。 而对可变集进行操作,改变的是该集合本身

4.4 映射

映射是一系列键值对的集合,类似于字典,键唯一,值不唯一,分为可变和不可变映射,同样地创建可变映射需要引入 scala.collection.mutable.Map

不可变映射

scala> val map1 = Map("name" -> "rose", "age" -> 18)
map1: scala.collection.immutable.Map[String,Any] = Map(name -> rose, age -> 18)

// 取值
scala> map1("name")
res10: Any = rose

scala> println(map1("name"))
rose

// 判断是否包含某个键
scala> map1.contains("age")
res12: Boolean = true

注意:不可变映射,是无法更新映射中的元素的,也无法增加新的元素。如果要更新映射的元素,就需要定义一个可变的映射

可变映射

scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map

scala> val map2 = Map("name" -> "rose", "sex" -> "female")
map2: scala.collection.mutable.Map[String,String] = Map(name -> rose, sex -> female)

// 获取元素
scala> map2("sex")
res0: String = female

// 添加新的元素,不是同一类型添加失败
scala> map2("age") = 18
<console>:14: error: type mismatch;
 found   : Int(18)
*  required: String
       map2("age") = 18
                     ^

scala> map2("age") = "18"

scala> map2
res3: scala.collection.mutable.Map[String,String] = Map(age -> 18, name -> rose, sex -> female)

// 添加新的映射(可一次添加多个)
scala> map2  = ("score" -> 98)
<console>:14: error: type mismatch;
 found   : Int(98)
 required: String
       map2  = ("score" -> 98)
                           ^

scala> map2  = ("score" -> "98")
res5: map2.type = Map(age -> 18, name -> rose, sex -> female, score -> 98)

// 重新赋值
scala> map2("name") = "lila"

scala> map2
res7: scala.collection.mutable.Map[String,String] = Map(age -> 18, name -> lila, sex -> female, score -> 98)
学新通

循环遍历映射

scala> for ((k, v) <- map1) println(k, v)
(name,rose)
(age,18)


scala> for (k <- map1.keys) println(k)
name
age

scala> for (k <- map1.values) println(k)
rose
18

4.5 数组

数组是一种可变的、可索引的、元素具有相同类型的数据集合,可以通过显示指定类型或者隐式推断实例化一个数组,包含:

  • 定长数组:长度不变的数组
  • 变长数组:长度可变

定长数组

// 定义一个长度为 3 的 Int 类型数组
scala> val intArr = new Array[Int](3)
intArr: Array[Int] = Array(0, 0, 0)

// 赋值
scala> intArr(0) = 1

scala> intArr(1) = 2

scala> intArr(2) = 3

scala> intArr
res3: Array[Int] = Array(1, 2, 3)

// 定义一个长度为 3 的 String 类型数组
scala> val strArr = new Array[String](3)
strArr: Array[String] = Array(null, null, null)

scala> strArr(0) = "name"

scala> strArr
res5: Array[String] = Array(name, null, null)

// 不指定数据类型
scala> val intArr2 = Array(1, 2, 3)
intArr2: Array[Int] = Array(1, 2, 3)
学新通

多维数组

// 定义个二维数组,三行四列
scala> val a1 = Array.ofDim[Int](3, 4)                                                                        
a1: Array[Array[Int]] = Array(Array(0, 0, 0, 0), Array(0, 0, 0, 0), Array(0, 0, 0, 0))                        
                                                                                                              
scala> a1(0)(0) = 1                                                                                           
                                                                                                              
scala> a1(0)(2) = 2                                                                                           
                                                                                                              
scala> a1(0)(1) = 3                                                                                           
                                                                                                              
scala> a1                                                                                                     
res9: Array[Array[Int]] = Array(Array(1, 3, 2, 0), Array(0, 0, 0, 0), Array(0, 0, 0, 0))                      

// 定义一个三维数组                                                                                              
scala> val a2= Array.ofDim[String](3, 2, 4)                                                                   
a2: Array[Array[Array[String]]] = Array(Array(Array(null, null, null, null), Array(null, null, null, null)), A
rray(Array(null, null, null, null), Array(null, null, null, null)), Array(Array(null, null, null, null), Array
(null, null, null, null)))                                                                                    
学新通

可变长数组

scala> import scala.collection.mutable.ArrayBuffer                                                 
import scala.collection.mutable.ArrayBuffer                                                        
                                                                                                   
scala> val a3 = ArrayBuffer(10, 20, 30)                                                            
a3: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10, 20, 30)                            
                                                                                                   
scala> a3  = 40                                                                                    
res10: a3.type = ArrayBuffer(10, 20, 30, 40)                                                       

// 在索引 2 的位置添加 60、80                                                                                           
scala> a3.insert(2, 60, 80)                                                                        
                                                                                                   
scala> a3                                                                                          
res12: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10, 20, 60, 80, 30, 40)             

// 移除 40                                                                                                 
scala> a3 -= 40                                                                                    
res13: a3.type = ArrayBuffer(10, 20, 60, 80, 30)                                                   
                                                                                                   
scala> val a4 = a3.remove(2)                                                                       
a4: Int = 60                                                                                       

// remove 不改变原数组                                                                                         
scala> a3                                                                                          
res14: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10, 20, 80, 30)                     
学新通

4.6 元组

元组与列表不同之处在于,元组(索引从 1 开始)可以是不同数据类型,列表必须是相同数据类型:

scala> val t1 = ("a", "b", "c", 1, 1.2)                                                      
t1: (String, String, String, Int, Double) = (a,b,c,1,1.2)                                    
                                                                                             
scala> println(t1._1)                                                                        
a                                                                                            
                                                                                             
scala> println(t1._2)                                                                        
b                                                                                            
                                                                            
scala> println(t1._3)                                                                        
c                                                                                            

4.7 迭代器

Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,它有两个方法:

  • hasNext:检测是否有下一个元素
  • next():获取下一个元素
scala> val iter1 = Iterator("A", "B", "C")
iter1: Iterator[String] = non-empty iterator

scala> while (iter1.hasNext) {println(iter1.next())}
A
B
C

scala> val iter2 = Iterator("A", "B", "C", "D")
iter2: Iterator[String] = non-empty iterator

// iter1 已经没有元素,所有没有输出
scala> for (elem <- iter1) {println(elem)}

scala> iter1
res25: Iterator[String] = empty iterator

scala> for (elem <- iter2) {println(elem)}
A
B
C
Dcala>
学新通

grouped、sliding 方法

  • grouped:返回元素的增量分块,有点类似于切片
  • sliding:生成一个滑动元素的窗口
scala> val xs = List(1, 2, 3, 4, 5)
xs: List[Int] = List(1, 2, 3, 4, 5)

scala> val a = xs grouped 3
a: Iterator[List[Int]] = non-empty iterator

// 一次获取三个元素
scala> a.next()
res0: List[Int] = List(1, 2, 3)

// 如果后面元素不足 3 个,有几个就返回几个
scala> a.next()
res1: List[Int] = List(4, 5)

// 一次获取三个元素,每调用一次 next(),就往后移动一位
scala> val b = xs sliding 3
b: Iterator[List[Int]] = non-empty iterator

scala> b.next()
res2: List[Int] = List(1, 2, 3)

scala> b.next()
res3: List[Int] = List(2, 3, 4)

scala> b.next()
res4: List[Int] = List(3, 4, 5)
学新通

其他方法

scala> val xs = List(1, 2, 3, 4, 5)
xs.size		// 获取元素个数
xs.length	// 获取迭代器长度
xs.toString()	// 将迭代器转换为字符串

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgabgfc
系列文章
更多 icon
同类精品
更多 icon
继续加载