Scala基于Java虚拟机的编程语言,也就是JYM的一门编程语言。所有Scala的代码,都需要经过编译为字节码,然后交由Java虚拟机来运行。
所以说,Scala和Java是可以无缝互操作的,Scala可以任意调用Java的代码。
Scala 安装及环境配置
修改配置文件:
vi /etc/profile
增加以下内容:
SCALA_HOME=/Users/apple/Documents/scala-2.11.8
export PATH=$PATH:$SCALA_HOME/bin
声明环境变量:
source /etc/profile
scala
:quit
Read(取值)->Evaluation(求值)->Print(打印)->Loop(循环)。Scala解释器也被称为REPL,会快速编译Scala代码为字节码,然后交由JVM来执行。
在scala>命令行内,键入scala代码,解释器会直接返回结果给你。如果未指定变量来存放这个值,默认名称为res,而且会显示数据类型。如Int,Double,String等。
例如:输入1+1,会返回res0:Int = 2
在后面可以继续使用res这个变量,以及它存放的值。
例如:2.1 * res0 ,返回res1:Double = 4.2
“Hi,” + res1 ,返回res2:String = Hi,4.2
在scala>命令行内,可以使用Tab进行自动补全。
例如:输入res2.to,敲击Tab,则会出现提示补全信息。
声明val变量来存放表达式的计算结果。
例如:val result = 1 + 1
后续也可继续使用这些变量。
但是常量声明后,是无法改变它的值的。
如果要声明的值可以改变的引用,可以使用var变量。
例如:var myresult = 2 , myresult = 3
在scala程序中,通常建议使用val,也就是常量,因为在类似于spark的大型复杂系统中,需要大量的网络传输数据,若使用var,可能会担心值被错误的更改。
五类声明var变量,还是var变量,都可以手动指定其类型,若不指定,scala会自动根据值,进行类型的判断。
例如:val name : String = null
例如:val name : Any = “leo”
可以将多个变量放在一起进行声明。
例如:val name1,name2:String = null;
例如:val num1,num2 = 100
Byte、Char、Short、Int、Long、Float、Double、Boolean。
scala没有基本数据类型与包装类型的概念,统一都是类。
并且,scala直接就可以调用大量的函数,如,1.toString()等。
scala中所有的数据都是对象。 e.g.: 1在java中是int,在scala中,1就是一个对象。
scala中字符串的插值操作(字符串的拼接)
var s1 : String = "Hello "
s1: String = "Hello "
"My name is Tom and ${s1}"
res1: String = My name is Tom and ${s1}
插值操作时,需要加入 s
scala> s"My name is Tom and ${s1}"
res2: String = "My name is Tom and Hello "
Unit类型和Nothing类型
<1>. Unit类型:即java中的void,没有返回值
val f = ()
f: Unit = ()
返回值 Unit类型
() 代表了一个函数,这个函数没有返回值
<2>. Nothing类型:在执行过程中,产生了异常Exception
注意:在Scala中定义变量可以不指定类型,Scala会进行类型的自动推导。
使用val申明变量
e.g.: scala> val answer = 8 * 3 + 2
可以在后续表达式中使用这些名称
val定义的值实际是一个常量
var申明其值可变的变量
scala使用很多加强类给数据类型增加了上百种增强的功能或函数。
例如:String类通过StringOps类增强了大量的函数。
例如:Scala还提供了RichInt、RichDouble等类型。
与Java类似。
Scala中无++、–操作符,只能使用+=和-=。
例如:import scla.matn._*后,可以使用sqrt(2),pow(2,4),min(3,Pi)。
调用函数时,不需要传递参数,scala允许调用函数时省略括号。
例如:“Hello World”.distinct
在Scala的object中,可以声明apply函数。而使用“类名()”的形式,其实就是“类名.apply()”的一种缩写。通常使用这种方式来构造类的对象。
- e.g.: 求两个数的最大值
- ```
_ 就相当于java中的 * ,代表包内所有内容
import scala.math._
max(1,2)
res4: Int = 2
定义了一个变量 res4 ,接收了 max 函数的返回值。scala中支持类型的推导。
```
语法:
def 函数名称([参数名称:参数类型]*) : 返回值类型 = {
函数的实现
}
```
使用for循环案例:
import util.control.Breaks._
import scala.math._
/**
*
* @ClassName: Demo1
* @Description
* @Author: YBCarry
* @Date2019-05-07 08:15
* @Version: V1.0
*
**/
object Demo1 {
def main(args: Array[String]): Unit = {
/*
* for 循环
* 定义一个集合
* */
var list = List("Mary", "Tom", "Mike")
println("--------for循环的第一种写法--------------")
/*
* <- 表示Scala中的generator,即:提取符 把list中的每一个元素,赋给s
* */
for (s <- list) println(s + " ")
println("--------for循环的第二种写法--------------")
//打印长度大于3的名字 加判断
for {
s <- list
if (s.length > 3)
} println(s)
println("--------for循环的第三种写法--------------")
//对第二种,进一步简化
for (s <- list if s.length <= 3) println(s)
println("--------for循环的第四种写法--------------")
/*
* 1、把list中所有元素,都变成大写
* 2、返回一个新的集合
* yield 记录每次迭代中的有关值,并逐一存入到新数组
* */
var newList = for {
s <- list
s1 = s.toUpperCase()
} yield (s1)
for (s <- newList) println(s)
println("--------while循环--------------")
//定义循环变量
var i = 0
while (i < list.length) {
println(list(i))
/*
* 自增
* 注意: scala中 没有 i++
* */
i += 1
}
println("--------do while循环--------------")
//定义一个循环变量
var j = 0
do {
println(list(j))
j += 1
} while (j < list.length)
println("--------for each 循环--------------")
/*
* foreach(没有返回值) scala里面有 spark里面会用到
* map循环(有返回值)
*
* foreach 说明
* foreach 是list的一个方法
* 把一个函数,传入了foreach —> 高阶函数(函数式编程)
* */
list.foreach(println)
/** 循环应用实例 */
/*
* 1. 判断101-200之间有多少个素数
*
* 判定素数的方法:
* x % 2 -- x % sqrt(根号) x
* 当都不能被整除的时候,就是素数
*
* e.g.:
* 16 sqrt(16)=4
* 故循环除2 3 4
* 验证能否被整除:16%2 == 0 ?
*
* 编程思路 —— 两层循环:
* 第一层 101-200
* 第二层 2 sqrt第一层
*
* */
println("-----------1. 判断101-200之间有多少个素数-------------")
println("-----------循环嵌套-------------")
var count: Int = 0 //保存结果
var index_outer = 0 //外层循环变量
var index_inner = 0 //内层循环变量
for (index_outer <- 101 until 200) {
var b = false //标识是否能被整除
index_inner = 2
/*
* scala中使用的是函数块的风格来解决break和continue的问题
* 相比java的一个关键词搞定的写法有点复杂
* 但符合函数式编程的风格
* */
breakable {
while (index_inner <= sqrt(index_outer)) {
if (index_outer % index_inner == 0) {
b = true
break
}
index_inner += 1
}
}
if (!b) count += 1
}
println("素数个数为:" + count)
/*
*1. 冒泡排序
*
* 算法分析:
* 1、比较相邻的元素。如果第一个比第二个大,就交换
* 2、对每一对相邻元素都做上述工作,循环完第一次后,最后的元素,就是最大的元素
* 3、针对剩下的元素,重复上面工作(除了最后一个元素)
*
* 程序分析:
* 1、两层循环
* 2、外层循环控制比较的次数
* 3、内层循环控制到达的位置,就是 结束比较 的位置
* */
println("-----------2. 冒泡排序-------------")
var a = Array(12, 3, 6, 2, 4, 7, 9, 5, 30, 1) //初始数据
println("-----------排序前-------------")
a.foreach(println)
for (i <- 0 until a.length - 1) {
for (j <- 0 until a.length - i - 1) {
if (a(j) > a(j + 1)) {
// 判断相邻元素大小
var tmp = a(j)
a(j) = a(j + 1)
a(j + 1) = tmp
}
}
}
println("-----------排序后-------------")
a.foreach(println)
}
}
val a = new Array[Int](10)
(10) 就是数组的长度
初始化赋给默认值
Array[String] = Array("Tom","Lily")
注意:不能往数组中添加不同类型的元素
import scala.collection.mutable._
val b = ArrayBuffer[Int]()
增加元素:
b += 1
b.type = ArrayBuffer(1)
b += 2
b.type = ArrayBuffer(1, 2)
b += (1,2,3,4)
b.type = ArrayBuffer(1, 2, 1, 2, 3, 4)
删除最后两个元素:
b.trimEnd(2)
scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 1, 2)
遍历数组:
for:for(s <- a ) println(s)
foreach:a.foreach(println)
最值:
b.max
b.min
排序:
降序:b.sortWith(_>_)
升序:b.sortWith(_<_)
创建X行Y列的数组
var c = Array.ofDim[Int](X,Y)
为x行y列赋值为n
c(x - 1)(y - 1) = n
定义一个二维数组,其中每个元素是一个一维数组,并且长度不固定
var d = new Array[Array[Int]](10)
for(i <- 0 until d.length){
d(i) = new Array[Int](i+1)
}
二维数组,如果使用 Array[Array[Int]](10) 声明时:
1、首先指定的是外层数据的长度
2、初始化内层数组的时候,再指定内层数组的长度
映射就是Map集合,由一个(key,value)对组成。
val scores = Map(“Alice” -> 10,”Bob” -> 3,”Cindy” -> 8)
映射的类型