1.scala和java
------- | java | scala |
---|---|---|
字符串 | Java需要采用“+”进行字符串的连接 | scala采用三个双引号“”“支持换行字符串 |
方法和返回值 | return | scala的return是可选的,方法调用会自动返回最后求值的表达式。如果scala使用了return则需要显示指定方法的返回值 |
类和方法修饰的默认值 | protected | problic |
默认导入的类 | java.lang | scala默认导入java.lang包、scala包、scala.Predef类 |
接口 | 支持接口:interface | 不支持接口,有类似抽象类的:Trait |
类成员和单例对象 | java由类成员,单例对象需要自己实现 | scala语言机制上支持单例对象和伴生对象,伴生类。伴生类和伴生对象需要在一个类文件中使用,在使用伴生对象时,系统隐式地调用apply生成一个伴生实例的对象。 |
2.数据类型和操作符
scala中的数据类型每一个都是一个类,scala会自己负责基本数据类型和引用类型的转换操作。因此使用上面的数据类型可以直接调用相关函数.
3. 声明值和变量
Scala声明变量有2种方式,var和val:
val定义的是不可变的变量,,称为只读变量
var:是可读变量,
scala默认匿名变量分配val
4.类结构图:
[类图](https://img-blog.csdnimg.cn/2020092609191347.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NpbmF0XzQyMjgzMzc4,size_16,color_FFFFFF,t_70#pic_center)
Scala中,所有的值都是类对象,而所有的类,包括值类型,都最终继承自一个统一的根类型Any。统一类型,是Scala的又一大特点。更特别的是,Scala中还定义了几个底层类(Bottom Class),比如Null和Nothing。
5.算术操作符的重载
+-*/%可以完成和Java中相同的工作,但是有一点区别,他们都是方法。你几乎可以用任何符号来为方法命名。
举例:
scala> 1 + 2
等同于:
scala> 1.+(2)
6.for 表达式
//to左右两边为前闭后闭的访问
for(i <- 1 to 3; j <- 1 to 3){
print(i * j + " ")
}
//until左右两边为前闭后开的访问
for(i <- 1 until 3; j <- 1 until 3) {
print(i * j + " ")
}
println()
//引入保护式(也称条件判断式)该语句只打印1 3。保护式满足为true则进入循环内部,满足为false则跳过,类似于continue
for(i <- 1 to 3 if i != 2) {
print(i + " ")
}
println()
//引入变量
for(i <- 1 to 3; j = 4 - i) {
print(j + " ")
}
println()
//将遍历过程中处理的结果返回到一个,使用yield关键字
val for5 = for(i <- 1 to 10) yield i
println(for5)
//输出结果:Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
//使用花括号{}代替小括号()
for{
i <- 1 to 3
j = 4 - i}
print(i * j + " ")
println()
7.函数
scala定义函数的标准格式:
def 函数名(参数名1: 参数类型1, 参数名2: 参数类型2) : 返回类型 = {函数体}
//返回Unit类型的函数
def shout1(content: String) : Unit = {
println(content)
}
//返回Unit类型的函数,但是没有显式指定返回类型。(当然也可以返回非Unit类型的值)
def shout2(content: String) = {
println(content)
}
//返回值类型有多种可能,此时也可以省略Unit
def shout3(content: String) = {
if(content.length >= 3)
content + "喵喵喵~"
else
3
}
//带有默认值参数的函数,调用该函数时,可以只给无默认值的参数传递值,也可以都传递,新值会覆盖默认值;传递参数时如果不按照定义顺序,则可以通过参数名来指定。
def shout4(content: String, leg: Int = 4) = {
println(content + "," + leg)
}
//递归函数在使用时必须有明确的返回值类型
def factorial(n: Int): Int = {
if(n <= 0)
1
else
n * factorial(n - 1)
}
8.懒值
当val被声明为懒值的时候,它的初始化会被推辞,只有第一次用到这个变量的时候,才会被调用,
object Lazy {
def init(): String = {
println("懒值执行了")
}
def main(args: Array[String]): Unit = {
lazy val msg = init()
println("lazy方法没有执行")
println(msg)
}
}
9.异常
抛出异常:用throw关键字,抛出一个异常对象。所有异常都是Throwable的子类型。throw表达式是有类型的,就是Nothing,因为Nothing是所有类型的子类型,所以throw表达式可以用在需要类型的地方。
捕捉异常:在Scala里,借用了模式匹配的思想来做异常的匹配,因此,在catch的代码里,是一系列case字句。
10.数组
定长数组
val arr1 = new Array[Int](10)
arr1(1) = 7
//定义
val arr1 = Array(1, 2)
变长数组
//定义
val arr2 = ArrayBuffer[Int]()
//追加值
arr2.append(7)
//重新赋值
arr2(0) = 7
定长数组和变长数组的相互转换
arr1.toBuffer
arr2.toArray
多维数组
//定义
val arr3 = Array.ofDim[Double](3,4)
//赋值
arr3(1)(1) = 11.11
java和scala相互转换:
val arr4 = ArrayBuffer("1", "2", "3")
//Scala to Java
import scala.collection.JavaConversions.bufferAsJavaList
val javaArr = new ProcessBuilder(arr4)
println(javaArr.command())
// java to scala
import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable.Buffer
val scalaArr: Buffer[String] = javaArr.command()
println(scalaArr)
数组遍历
for(x <- arr1) {
println(x)
}
11 元组:
元组可以理解为一个容器,可以存放各种相同或者不同的数据类型,一个元组最多有22行元素.元组可以new,也可以不new.
1.元组的创建
val tuple1 = (1, 2, 3, "heiheihei")
println(tuple1)
2.元组的访问:
val value1 = tuple1._4
println(value1)
3.元组的遍历
for (elem <- tuple1.productIterator) {
print(elem)
}
println()
12.列表
//创建列表
val list1 = List(1, 2)
println(list1)
//访问列表元素
val value1 = list1(1)
println(value1)
//列表追加元素
val list2 = list1 :+ 99
println(list2)
val list3 = 100 +: list1
println(list3)
//List的创建与追加,符号“::”,注意观察去掉Nil和不去掉Nil的区别,Nil表示为空
val list4 = 1 :: 2 :: 3 :: list1 :: Nil
println(list4)
//
13 映射
1.构造不可变的映射
val map1 = Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> 30)
2.构造可变映射
val map2 = scala.collection.mutable.Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> 30)
3.空映射
val map3 = new scala.collection.mutable.HashMap[String, Int]
4.对偶元组
val map4 = Map(("Alice", 10), ("Bob", 20), ("Kotlin", 30))
14 set集合
默认情况下,scala使用的是不可变的集合,如果想用可变集合,则需要引用scala.collection.Set 包
1.set不可变集合的创建
val set = Set(1, 2, 3)
println(set)
2.set可变集合创建,如果import了可变集合,那么后续使用默认也是可变集合
import scala.collection.mutable.Set
val mutableSet = Set(1, 2, 3)
3.可变集合元素添加
mutableSet.add(4)
mutableSet += 6
// 注意该方法返回一个新的Set集合,而非在原有的基础上进行添加
mutableSet.+(5)
4.可变集合元素删除
mutableSet -= 1
mutableSet.remove(2)
println(mutableSet)
5.集合元素与函数的映射
//map::将集合中的每一个元素映射到某一个函数
val names = List("Alice", "Bob", "Nick")
println(names.map(_.toUpperCase))
// flatmap::flat即压扁,压平,扁平化,效果就是将集合中的每个元素的子元素映射到某个函数并返回新的集合
val names = List("Alice", "Bob", "Nick")
println(names.flatMap(_.toUpperCase()))
15 折叠,化简,扫面
将二元函数引用于集合中的函数
val list = List(1, 2, 3, 4, 5)
val i1 = list.reduceLeft(_ - _)
val i2 = list.reduceRight(_ - _)
println(i1)
println(i2)
1,flod:折叠
val list2 = List(1, 9, 2, 8)
val i4 = list2.fold(5)((sum, y) => sum + y)
println(i4)
2.统计一句话中,各个文字出现的频次.
val list2 = List(1, 9, 2, 8)
val i4 = list2.fold(5)((sum, y) => sum + y)
println(i4)
16. trait
package com.zhou
/**
* 一个类继承多个trait时,第一个用extends,后面都用with
* trait不可以传参
*
*/
trait read{
def read1(name:String)={
println(s"$name is reading")
}
}
trait listen{
def listen1(name:String)={
println(s"$name is listening")
}
}
class human() extends read with listen {
}
object map {
def main(args: Array[String]): Unit = {
val human = new human()
human.read1("zhangshan")
human.listen1("zhou")
}
}
trait 方法体的实现和不实现
package com.zhou
/**zhouhonglin
* trait方法体的实现和方法体的不实现
*类继承了trait要实现trait中没有实现的方法
*o.isInstanceOf[Point]&&o.asInstanceOf[Point].x==this.x
* isInstanceOf判断是否为point的实例,如果是,就做为point的实例,取出x和谁调用的x进行比较
*
*/
trait IsEqual{
def isEqu(o:Any):Boolean
def isNotEqu(o:Any):Boolean = !isEqu(o)
}
class Point(xx:Int, yy:Int) extends IsEqual{
val x = xx
val y = yy
override def isEqu(o: Any): Boolean = {
o.isInstanceOf[Point]&&o.asInstanceOf[Point].x==this.x
}
}
object trait1 {
def main(args: Array[String]): Unit = {
val p1 = new Point(1,2)
val p2 = new Point(1,3)
println(p1.isEqu(p2))
}
}
17.模式匹配
Match