目录
6.1.1 可变的: ArrayBuffer : 理解为java的ArrayList
override def show():Unit = println(s"Person's legs is ${legs}")}
Scala等否替代Java?答案是不能!!!因为Java的强大不是在于语法,那么Java强大在于他的生态。
1 Scala与java的关系
- 基于JVM运行 :scala编译的文件也是.class字节码,转为字节码运行在JVM虚拟机上
- 两者可以相互调用:Scala和Java之间的包以及方法都可以相互调用的。
- 面向函数式编程:Java8的lambda表达式就是面向函数编程的,Scala是面向函数和面向对象的语言。
- Java设计之初是OOP(封装、继承、多态,反正就是面向对象的),Scala设计之初是为了FOP。
2 Scala的数据类型
数据类型 | 描述 |
---|---|
Byte | 8bit的有符号数字,范围-128~127 |
Short | 16bit,-32768~32767 |
Int | 32bit |
Long | 64bit |
Float | 32bit |
Double | 64bit |
Char | 16bit Unicode编码,U+0000 到 U+FFFF |
String | 字符串:序列Seq |
Boolean | 布尔类型 |
Unit | 表示无值,有点像Java中void。但在scala中的函数使用Unit实际上返回的空元组:() |
Null | 空引用或空值 |
Nothing | 所有其他类型的类型,表示没有值 |
Any | 所有类型的超类,任何实力都属于Any类型的 |
AnyRef | 所有应用类型的超类 |
scala拥有和java几乎一样的类型,和java的数据类型的内存布局也完全一致,精度也完全相同。
有关Any和AnyRef的一些说法: val p = new Person(),Person对象(就是p)父类是Any,Person{}的超类就是AnyRef。
3 运算符
和Java类似。
scala的++和--是用于连接两个集合,不是做运算的!
4 流程控制语法
4.1 if表达式
package com.qf.bigdata object TestDemo12 { def main(args: Array[String]): Unit = { val res = testIf() println(res) } def testIf():Unit = { val age = 18 val res:String = if (age >16) return "adult" else return "child" println(res) } }
结果是一个空元组,但是if也可以做返回值
4.1.2 if自己本身返回
package com.qf.bigdata object TestDemo13 { def main(args: Array[String]): Unit = { val age = 18 val res:String = if(age>18) "adult" else "child" print(res) } }
4.2 循环
4.2.1 breakable语句块
因为Scala没有break,只能使用breakable把语句进行隔离
breakable{}代码块是针对break跳出的范围,break当然也在breakable{}中
package com.qf.bigdata import scala.io.StdIn import scala.util.control.Breaks._ object TestDemo13 { def main(args: Array[String]): Unit = { println("*"*100) println("welcome") println("*"*100) var count = 3 breakable{ while(true){ while(count > 0){ count = count - 1 val username:String = StdIn.readLine("input your username:") val password :String = StdIn.readLine("input your password:") if(username == "admin"&& password =="123456"){ println(s"welcome to${username}!") break //跳出循环 }else{ println(s"用户名或者密码错误,您还有${count}次机会") if(count == 0) { println("对不起,您没有机会了") break } } } } } } }
4.2.2 for
package com.qf.bigdata object TestDemo13 { def main(args: Array[String]): Unit = { //for的遍历 for(i <- 1 to 10){ //包头包尾 println(s"i = ${i}") } println("-"* 10) var range = 1.to(10) //就是先把那个范围拿出来,用一个变量放在循环 for(i <- range){ println(s"i = ${i}") } println("-"* 10) //直接使用范围用foreach进行遍历 range.foreach(i =>println(s"k=${i}")) println("-"*10) range.foreach(println(_)) println("-"*10) range.foreach(println) } }
4.3 异常控制
说明:
scala的异常不需要我们手动抛出,代码底层会处理那些不能避免的异常。
Java遇到不可处理的异常就是throw,scala底层对于不可处理的异常会处理哦!
下面是编写捕获异常的代码,其实try{}catch{}一样,就是里面的异常用了类型匹配
package com.qf.bigdata
object TestDemo13 { def main(args: Array[String]): Unit = { try{ var i = 1/0 }catch { case e :ArithmeticException=>{ println("ArithmeticException") } case e :NumberFormatException =>{ e.printStackTrace() } case e:Exception =>{ println("文件找不到") } } } }
5 函数
函数一般是有返回值的,就是直接放在函数体的最后一行就可以了,不需要写return
5.1 普通函数
package com.qf.bigdata object TestDemo13 { def main(args: Array[String]): Unit = { val s = show() val hi = sayHi("cidy") println(s) //首先是执行show,但是这个函数unit所以就返回( println(hi) } def show (): Unit ={ println("abce") } def sayHi(name:String):String ={ "Nice to meet you" +name } }
5.2 特殊函数
5.2.1 单行函数
所谓单行函数,顾名思义就是只有一行的函数。需要注意的是,单行函数,必须使用"="来作为函数的返回值类型推断 。
def sayHi(name:String):String = "Nice to meet you" +name
5.2.2 无参函数
参数列表为空的函数,()可以省略,如果()省略,那调用的时候()也要省略。
package com.qf.bigata.scala
object Demo7 {
def main(args: Array[String]): Unit = {
show()
showshowtime
showtime()
}def show() = println("abcde")
def showtime = println("fg")
}
5.2.3 默认参数函数
就是函数的参数列表中直接赋值给参数,这样调用函数的时候就可以不用赋值啦。
package com.qf.bigdata object TestDemo13 { def main(args: Array[String]): Unit = { show("zs",18) } def show (name:String,age:Int,city:String="shenzhen") = println(s"${name},${age},${city}") }
5.2.4 带名参数的函数
就是调用函数的时候直接声明函数参数名调用啦。
package com.qf.bigdata object TestDemo13 { def main(args: Array[String]): Unit = { show(name ="zs",age=18) } def show (name:String,age:Int,city:String="shenzhen") = println(s"${name},${age},${city}") }
5.2.5 可变参数
我们先回顾一下java的可变参数
public void show(int ... nums){
}
其实scala的可变参数就是对数组可变参数的一种表示而已了。
package com.qf.bigdata object TestDemo13 { def main(args: Array[String]): Unit = { //第一种写法 println(add(1,2,3,4)) //第二种写法,我不太熟悉 val arr = Array(1,2,3,4) println(add(arr:_*)) } def add(arr:Int*) ={ var sum =0 for(a <- arr) sum += a sum } }
6 集合类型
6.0 集合体系
-
Iterable: 其中Iterable是所有集合的根trait。
-
Seq(IndexSeq): 指一个有先后顺序的的序列,比如数组或者列表(List)。IndexSeq允许我们通过下标索引快速访问任意元素的序列。比如:ArrayBuffer。链表也是序列,链表不是IndexSeq。
-
Set(SortedSet):是一组没有先后顺序的集合。但是sortedSet中,元素可以某种排序被访问。
-
Map(SortedMap):一组对偶。
6.1 数组
6.1.1 可变的: ArrayBuffer : 理解为java的ArrayList
package com.qf.bigata.scala
import scala.collection.mutable.ArrayBuffer
object Demo11 {
def main(args: Array[String]): Unit = {
//1. 定义
val buffer1 = new ArrayBuffer[Int]()
val buffer2: ArrayBuffer[String] = ArrayBuffer[String]("lixi", "rock")//2. crud
println(buffer2.length)
println("增---------------------------->")
buffer2.append("lee")
println(buffer2.length)
buffer2.append("rocklee", "sakura", "narudo")
println(buffer2.length)
println(buffer2.mkString(","))
buffer2.insert(3, "2b")
println(buffer2.mkString(","))println("查---------------------------->")
println(buffer2(3))
println(buffer2.size)println("改---------------------------->")
buffer2(3) = "sb"
println(buffer2.mkString(","))println("删---------------------------->")
buffer2.remove(3) // 删除指定索引位置上的元素
println(buffer2.mkString(","))
buffer2.remove(3, 2)
println(buffer2.mkString(","))//drop : 不是删除原数组,将原数组中的元素在内存中做副本删除之后生成新的副本
println("drop---------------------------->")
println(buffer2.mkString(","))
val buffer3: ArrayBuffer[String] = buffer2.drop(2) // 按照左边顺序删除2个元素,生成新的副本
println(buffer2.mkString(",")) // drop不会对原数组造成破坏
println(s"buffer3: ${buffer3.mkString(",")}") // drop不会对原数组造成破坏
val buffer4: ArrayBuffer[String] = buffer2.dropRight(2)
println(s"buffer4: ${buffer4.mkString(",")}") // drop不会对原数组造成破坏
}
}
6.1.2 不可变的:Array:理解为java的普通数组
package com.qf.bigata.scala
object Demo10 {
def main(args: Array[String]): Unit = {
//1. 定义数组
//1.1 类似于java中的动态初始化数组
val array1 = new Array[Int](5) // 自定义一个Int类型数组,并且数组长度是5,每个数组元素默认值为0
array1.foreach(println)
println("-" * 10)//1.2 类似于java中的静态初始化数组:伴生对象方式创建
val array2 = Array(1,2,3,4) // 自定义一个Int类型数组,并且数组长度是4,数组元素分别为:1,2,3,4
array2.foreach(println)
println("-" * 10)//2. 获取到数组的元素:数组名(index)
println(array2(2)) // java:array2[2]
println("-" * 10)//3. 数组的遍历
/*
* //3.1 传统写法
* for(element <- 数组名) {
* element : 数组中的每个元素
* }
*
* //3.2 函数式编程的写法
* 数组名.foreach(element => {
* element : 数组中的每个元素
* })
*///4. 数组的长度
println(array2.length)
println(array2.size)
println("-" * 10)//5. 判断一个数组元素是否在一个数组中
println(s"判断3是不是在array2的数组中:${array2.contains(-3)}")
println("-" * 10)//6. 数组元素拼接 : mkString
println(s"数组元素:${array2.mkString}") // 没有分隔符
println(s"数组元素:${array2.mkString(",")}&#