1.数组Array
1.1定长数组
1.1.1 定义方式
//通过new的方式
val arr1 = new Array [Int] (3) //指定长度为3。Int类型初始化为0
val arr2 = new Array [String] (3) //String类型初始化为null
//通过apply方法
val arr3 = Array(1,“scala”,3,14)
val arr4 = Array.apply(1,“scala”,3,14)
说明:apply方法内部通过new Array [T] ()
1.1.2 通过下标赋值、修改值
//定长数组赋值、修改
arr2(0) = “章子怡”
arr2(1) = “王菲”
arr2(1) = “鞠婧祎”
返回:ArrayBuffer(章子怡, 鞠婧祎, null)
1.1.3 数组转List
//数组转List
val list1: immutable.Seq[String] = arr2.toList
val list2: List[String] = arr2.toList
1.1.4 遍历数组元素
//通过下标取值
for (i <- 0 until arr3.length) {
println(s" i = = i== i=={arr4(i)}")
}
//直接循环出数组元素
for (i <- arr4) {
println(i)
}
1.2变长数组
import scala.collection.mutable.{ArrayBuffer, ListBuffer} //依赖包
1.2.1定义方式
//通过new的方式
val buffer1 = new ArrayBuffer[String] ()
buffer1 += “王祖贤”
buffer1 += “林青霞”
//通过apply方法
val buffer2 = ArrayBuffer(“赵丽颖”,“鞠婧祎”)
val buffer3 = ArrayBuffer.apply(“李一桐”,“周迅”)
1.2.2 删除元素
buffer3.remove(1) //删除下标为1的元素
1.2.3 排序
//排序
val buffer4 = ArrayBuffer(1,3,5,7,6,4,2,0)
val buffer4_1 = buffer4.sortWith(<)
val buffer4_2 = buffer4.sortWith((x,y) => x < y)
2.集合Map
2.1不可变map
2.1.1定义方式
//通过-> 来定义Map或者元组方式
val map1:Map[String,Int] = Map(“鞠婧祎” -> 25, “刘亦菲” -> 31)
val map2 = Map((“杨钰莹”,44),(“邓丽君”,46))
2.1.2 遍历元素
for (i <- map1) {
println(i)
}
for ((k,v) <- map1) {
println(k,v)
}
//迭代循环
for (i <- map1.iterator) {
println(i)
}
//增强循环
map1.foreach(tuple => {
println(tuple._1,tuple._2)
})
2.1.3 取值
val keys = map1.keySet //获取所有key
val values = map1.values //获取所有value
val value1 = map1.getOrElse(“杨紫”,“无此值”) //获取对应key的value
2.2可变map
import scala.collection.{immutable, mutable} //依赖包
2.2.1 定义方式
val mmap = mutable.Map[String, String] () //需要指定泛型
val mmap2 = mutable.Map.empty[String, Int]
val hmap = mutable.HashMap[String,String] () //需要指定泛型
val hmap2 = mutable.HashMap.empty[String, Int]
2.2.2 添加元素
mmap += “杨幂” -> “女”
mmap += (“杨紫” -> “女”, “任嘉伦” -> “男”)
mmap += ((“刘亦菲”, “女”), (“胡歌”, “男”), (“涂磊”, “未知”),(“鞠婧祎”,“女”))
2.2.3 删除元素
mmap -= “刘亦菲”
2.2.4 修改元素
mmap.update(“涂磊”, “男”)
2.2.5 根据key获取值
hmap += ((“杨幂”,“三生三世十里桃花”),(“鞠婧祎”,“叹云夕”),(“胡歌”,“琅琊榜”),(“任嘉伦”,“白蛇传说”),(“杨紫”,“白蛇传说”))
val it: Iterable[String] = mmap.keys
var value: Option[String] = null
it.foreach(key => {
value = hmap.get(key) //一般使用getOrElse(“key值”,“默认值”)
value match {
case None => println(s" k e y = = 未 主 演 电 视 剧 " ) c a s e S o m e ( o t h e r V a l u e ) = > p r i n t l n ( s " key==未主演电视剧") case Some(otherValue) => println(s" key==未主演电视剧")caseSome(otherValue)=>println(s"key==$otherValue")
}
})
说明:
默认创建的map为不可变的map, Map() immutable.Map()
如果创建可变的map必须要使用mutable;mutable.MapA,B
可变和不可变的区别:
a 定义使用的关键字不一样
b 不可变的map如果使用 val修饰,则不能修改其值,但是可变的map无论用var或者val修饰都可以修改其值
c 不可变的map在更新其值之后会返回一个新的map,但是可变的map修改其值将修改原map值,返回unit
3.列表List
3.1 不可变List
3.1.1 定义方式
val lis1 = List(“贾静雯”, “安以轩”, “杨幂”, “高圆圆”)
3.1.2 添加元素
val lis2 = lis1 :+ “黎姿” //末尾添加
val lis3 = “张敏” +: lis2 //列表头部添加
3.2 可变List
3.2.1 定义方式
val lbf1: ListBuffer[String] = new ListBuffer[String] ()
val list = mutable.ListBuffer.empty[String]
val list2 = mutable.ListBufferString
3.2.2 添加元素
lbf1 += “飞狐外传”
lbf1 += “雪山飞狐”
lbf2 += “连城诀”
lbf2 += “天龙八部”
lbf2.append(“射雕英雄传”)
lbf2.append(“白马啸西风”)
4.Set
//不可变Set
val set1: Set[String] = Set[String] () //特质,不能new。通过apply方法
val set2: Set[String] = new HashSet[String] () //new 其子类对象
//可变Set
val mset3: mutable.Set[String] = mutable.Set ()
val mset = mutable.Set.empty[String]
val hashSet = new mutable.HashSet[String] ()
val mhset = mutable.HashSet.empty[String]
hashSet += “笑傲江湖”
hashSet.add(“书剑恩仇录”)
5.for过滤器
5.1 函数
//for过滤器函数
val grepFunc = (books: ArrayBuffer[String], grepPattern: String) => {
if (books != null) {
val greps: ArrayBuffer[String] = for {
book <- books
if (book.contains(grepPattern))
} yield book
println(greps)
}
}
5.2 方法
//for过滤器方法
def grep(books: ArrayBuffer[String]): ArrayBuffer[String] = {
var greps: ArrayBuffer[String] = null
if (books != null) {
greps = for {
book <- books
if (book.length == 3)
} yield book
}
greps
}
5.3 测试
val buffer2 = ArrayBuffer[String] ()
buffer2 += (“武林外史”,“绝代双骄”,“楚留香传奇”,“多情剑客无情剑”,“萧十一郎”,“流星蝴蝶剑”,“边城浪子”,
“陆小凤传奇”,“孔雀翎”,“天涯明月刀”,“三少爷的剑”,“圆月弯刀”,“小李飞刀”,“浣花洗剑录”)
5.4 scala中的循环中断
package scalaDemo
import util.control.Breaks._
object CircleBreak {
def main(args: Array[String]): Unit = {
//方式1:通过调用break函数实现中断
var num1 = 0
breakable {
while (num1 <= 50) {
if (num1 % 2 != 0) {
println(s"num1==$num1")
}
if (num1 == 9) {
println("while循环中断...\r\nfor循环开始...")
break()
}
num1 += 1
}
}
breakable {
for (num2 <- 1 to 50) {
if (num2 % 2 == 0) {
println(s"num2==$num2")
}
if (num2 == 10) {
println("for循环中断...\r\n")
break()
}
}
}
//方式2:通过循环守卫实现中断
var flag = true
//def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step)
for (num3 <- Range(1, 10, 2) if flag) {
if (num3 == 5) {
flag = false
println("结束循环...")
} else {
println(s"num3==$num3")
}
}
//方式3:通过引入外部变量
val arr = Array('a','b','c','d','e','f')
var i = 0
var elem = ' '
var tmpf = true
while ({elem = arr(i); i <= arr.length && tmpf}) {
if (elem != 'd') {
println(elem)
} else {
println("结束循环...")
tmpf = false
}
i +=1
}
}
}
5.5 scala中循环实现continue效果
package scalaDemo
object CircleContinue {
def main(args: Array[String]): Unit = {
//方式1:通过循环守卫实现continue效果
for (i <- 1 to 10 if i % 2 == 0) {
println(s"i==$i")
}
var j = 0
while (j <= 10) {
//方式2:通过if表达式实现continue效果
if (j % 2 != 0) {
println(s"j==$j")
}
j +=1
}
}
}
6.scala中的变长参数
//变长参数
def method1(author: String, books: String*): String = {
val buffer = new StringBuffer()
var res: String = “”
if (!author.isEmpty && books != null) {
buffer.append(author + “:”)
for (book <- books) {
buffer.append(book + “|”)
}
val tmpStr = buffer.toString
res = tmpStr.substring(0,tmpStr.length-1)
}
res
}
//测试
val res1 = method1(“古龙”,“武林外史”,“绝代双骄”,“楚留香传奇”,“多情剑客无情剑”,“萧十一郎”,“流星蝴蝶剑”,“边城浪子”)
println(res1)
备注:scala中的变长参数只允许有一个,且必须在末尾
7.类
7.1 内部类
class CircleArea {
private[this] var r: Double = _
private[this] var s: Double = _
def rget: Double = r
def rset(r: Double): Unit = {
this.r = r
}
//圆面积
def getCircleArea: Double = {
this.s = 3.14*Math.sqrt®
s
}
//圆柱体积(内部类可以访问外部类中的属性)
class CylinderVolume {
private[this] var h: Double = _
var v: Double = _ //外部类无法访问内部类中的属性
def hget: Double = h
def hset(h: Double): Unit = {
this.h = h
}
//体积
def getCylinderVolume: Double = {
s*h
}
}
//获取内部类
def getInnerCylinderVolume: CylinderVolume = {
val cylinderVolume = new CylinderVolume
cylinderVolume
}
}
object CircleArea {
def main(args: Array[String]): Unit = {
val r: Double = 6
val h: Double = 1
val circleArea = new CircleArea
circleArea.rset®
val s = circleArea.getCircleArea
//内部类不能直接new,需要提供一个方法
val cylinderVolume = circleArea.getInnerCylinderVolume
cylinderVolume.hset(h)
val v = cylinderVolume.getCylinderVolume
println(s"r: $r\r\nh: $h\r\ns: $s\r\nv: $v")
}
}
7.2 主构造器
//主构造器参数用val修饰后,将不能再次赋值
class Demo3(var book: String, var author: String) {
def myMethod1(book: String, author: String): Unit = {
this.book = book
this.author = author
}
override def toString: String = s"书名: $book 作者: $author"
}
object TestMain {
def main(args: Array[String]): Unit = {
val demo1 = new Demo3(“射雕英雄传”,“金庸”)
println(demo1)
demo1.myMethod1(“楚留香传奇”,“古龙”)
println(demo1)
}
}
package scalaDemo.chapter.chapter02
object Test_Variable {
def main(args: Array[String]): Unit = {
val stu1 = new Student01("赵敏", 20, "清华大学")
//1.Student01对象中的name属性访问不到,没有用val或var修饰
//2.由于age被val修饰,值不可修改。而school被var修饰,值可以修改
// stu1.age = 18
stu1.school = "北京大学"
stu1.stuInfo
/**
* 总结:主构造器中name、age、school都会被编译成私有成员变量和构造方法
* private final String name;
* private final int age;
* private String school;
*
* public Student01(String name, int age, String school) {}
*
* val修饰的变量会生成公有的类似java中的"get"方法
* public int age() {
* return this.age;
* }
*
* val修饰的变量会生成公有的类似java中的"get"方法和 "set"方法
* scala中用变量名()和变量名_$eq()来表示
* public String school() {
* return this.school;
* }
*
* public void school_$eq(String x$1) {
* this.school = x$1;
* }
*
*
**/
}
}
class Student01(name: String, val age: Int, var school: String) {
def stuInfo = {
println(s"name=$name age=$age school=$school")
}
}
7.3 辅助构造器
//主构造器private修饰,仅限于当前类、伴生对象访问;private[this]表示仅限于当前类访问
class Demo5 private (var author: String, var bookName: String) {
private var star: String = _
private[this] var fan: String = _ //关键字this,伴生对象无法访问该属性
//辅助构造器1
def this(author: String, bookName: String,star: String) = {
this(author,bookName) //调用主构造器
this.star = star
}
//辅助构造器2 (方式1)
// def this(author: String, bookName: String,star: String,fan: String) = {
// this(author,bookName)
// this.star = star
// this.fan = fan
// }
//辅助构造器2 (方式2)
def this(author: String, bookName: String,star: String,fan: String) = {
this(author,bookName,star) //调用辅助构造器1
this.fan = fan
}
override def toString: String = {
s"author: $author\r\nbookName: $bookName\r\nstar: $star\r\nfan: $fan"
}
}
object Demo5 {
def main(args: Array[String]): Unit = {
//主构造器创建对象
val demo1 = new Demo5(“古龙”,“小李飞刀”)
//辅助构造1器创建对象
val demo2 = new Demo5(“古龙”,“小李飞刀”,“萧蔷”)
//辅助构造器2创建对象
val demo3 = new Demo5(“古龙”,“小李飞刀”,“萧蔷”,“高晓松”)
println(demo1)
println(demo2)
println(demo3)
}
}
7.4 自定义apply方法
//主构造器private修饰,仅限于当前类、伴生对象访问;private[this]表示仅限于当前类访问
class Demo6 private (var author: String, var bookName: String) {
private var star: String = _
private[this] var fan: String = _ //关键字this,伴生对象无法访问该属性
//辅助构造器1
def this(author: String, bookName: String,star: String) = {
this(author,bookName) //调用主构造器
this.star = star
}
//辅助构造器2 (方式1)
// def this(author: String, bookName: String,star: String,fan: String) = {
// this(author,bookName)
// this.star = star
// this.fan = fan
// }
//辅助构造器2 (方式2)
def this(author: String, bookName: String,star: String,fan: String) = {
this(author,bookName,star) //调用辅助构造器1
this.fan = fan
}
override def toString: String = {
s"author: $author\r\nbookName: $bookName\r\nstar: $star\r\nfan: $fan"
}
}
//自定义apply方法
object Demo6 {
//定长参数
def apply(author: String, bookName: String): Demo6 = {
val demo = new Demo6(author,bookName)
demo
}
//定长参数
def apply(author: String, bookName: String, star: String): Demo6 = {
val demo = new Demo6(author,bookName,star)
demo
}
//变长参数
def apply(author: String, str: String*): Demo6 = {
var demo: Demo6 = null
if (!str.isEmpty && str != null) {
demo = new Demo6(author,str(0),str(1),str(2))
}
demo
}
}
object Demo6Test {
def main(args: Array[String]): Unit = {
Array(1,2)
val demo1 = Demo6(“古龙”,“小李飞刀”)
val demo2 = Demo6(“古龙”,“小李飞刀”,“萧蔷”)
val demo3 = Demo6(“古龙”,“小李飞刀”,“萧蔷”,“高晓松”)
println(demo1)
println(demo2)
println(demo3)
}
}
7.5 setter和getter方法
package scalaDemo
object ClassTest {
def main(args: Array[String]): Unit = {
val person = new Person()
person.name = "鞠婧祎" //person.name_$eq("鞠婧祎")
person.gender = "女" //person.gender_$eq("女")
// person.age = 26 //person.age_$eq(26)
}
}
class Person {
private val privateDescription: String = "私有属性-人类" //生成的字节码文件中,只有私有的getter方法--pirvate String privateDescription()
val publicDescription: String = "公有属性-动物" //生成的字节码文件中,只有公有的getter方法--public String publicDescription()
var name: String = _ //var修饰的变量,编译成的字节码文件中,既有setter方法又有getter方法
protected var gender1: String = _ //当前类及其子类对象可以访问
protected[scalaDemo] var gender2: String = _ //String和引用类型的变量,使用"_"初始化时全部为null
private var age: Int = _ //val修饰的属性,字节码文件只有getter方法,而var修饰的属性,字节码文件既有setter又有getter方法
}
/*
public class Person {
private final String privateDescription = ";
private String privateDescription() {
return this.privateDescription;
}
private final String publicDescription = ";
private String name;
private String gender;
private int age;
public String publicDescription() {
return this.publicDescription;
}
public String name() {
return this.name;
}
public void name_$eq(String x$1) {
this.name = x$1;
}
public String gender() {
return this.gender;
}
public void gender_$eq(String x$1) {
this.gender = x$1;
}
private int age() {
return this.age;
}
private void age_$eq(int x$1) {
this.age = x$1;
}
}
*/
class Demo4 {
private val reader: String = “张韶涵”
private var bookName: String = _ //当前类及其伴生对象可以访问
private[this] var author: String = _ //this表示只能在当前类中访问,伴生对象无法访问
//getter方法和setter方法
def bookname: String = bookName
def bookname_=(bookName: String): Unit = {
this.bookName = bookName
}
def authors: String = author
def authors_=(author: String): Unit = {
this.author = author
}
}
object Demo4Test {
def main(args: Array[String]): Unit = {
val class1 = new Demo4
class1.bookname_=(“西游记”)
class1.authors_=(“吴承恩”)
println(class1.bookname)
println(class1.authors)
}
}
说明:
1.scala中是没有getter和setter说法的,当成员变量用private、private[this]等修饰时,
可以提供一对方法,如:method、method_=来替代getter、setter方法
7.6 继承及多态
import scala.collection.mutable.ArrayBuffer
import scala.util.Random
abstract class Animals {
var name: String = _
var age: Int = _
var sex: String = _
def action: String
}
class Persion extends Animals {
private var university: String = _
def this(name: String, age: Int, sex: String) = {
this()
this.name = name
this.age = age
this.sex = sex
}
def this(name: String, age: Int, sex: String, university: String) = {
this(name, age, sex)
this.university = university
}
override def action: String = {
s"name: $nameage: $agesex: $sexuniversity: $universityaction: 喜欢看书、玩游戏、恋爱…"
}
override def toString: String = {
s"name: $nameage: $agesex: $sex**university: $university"
}
}
class Dog extends Animals {
private var food: String = _
def this(name: String, age: Int, sex: String) = {
this()
this.name = name
this.age = age
this.sex = sex
}
def this(name: String, age: Int, sex: String, food: String) = {
this(name, age, sex)
this.food = food
}
override def action: String = {
s"name: $nameage: $agesex: $sexfood: $foodaction: 喜欢卖萌、奔跑、啃骨头…"
}
override def toString: String = s"name: $nameage: $agesex: $sex**food: $food"
}
class Bird extends Animals {
private var flyHigh: Double = _
def this(name: String, age: Int, sex: String) = {
this()
this.name = name
this.age = age
this.sex = sex
}
def this(name: String, age: Int, sex: String, flyHigh: Double) = {
this(name, age, sex)
this.flyHigh = flyHigh
}
override def action: String = {
s"name: $nameage: $agesex: $sexflyHigh: $flyHighaction: 喜欢翱翔、高飞、叽叽喳喳…"
}
override def toString: String = s"name: $nameage: $agesex: $sex**flyHigh: $flyHigh"
}
object ExtendsDemo {
def main(args: Array[String]): Unit = {
val persion: Animals = new Persion(“人类”, 100, “female”, “清华大学”)
val dog = new Dog(“狗类”, 10, “male”, “骨头”)
val bird = new Bird(“鸟类”, 6, “female”, 999)
val buffer: ArrayBuffer[Animals] = new ArrayBuffer
buffer += (persion, dog, bird)
println(buffer)
//多态。父类引用指向子类对象
val animals: Animals = buffer(Random.nextInt(buffer.length))
println(animalAction(animals))
}
//定义一个方法
def animalAction(animal: Animals): String = {
animal.action //实际调用子类中的方法
}
}
7.7 类型判断和类型转换
import scala.collection.mutable.ListBuffer
import scala.util.Random
abstract class Animal {
var name: String = _
var age: Int = _
def action: String
}
class Persion2(var sex: String) extends Animal {
private var favoriteStar: String = _
def this(name: String,age: Int,sex: String) = {
this(sex)
this.name = name
this.age = age
}
def this(name: String,age: Int,sex: String,favoriteStar: String) = {
this(name,age,sex)
this.favoriteStar = favoriteStar
}
def persionMethod: Unit = {
println(“Persion类:”+this.getClass)
}
override def action: String = s"喜欢看书、玩游戏、恋爱…"
override def toString = s"姓名: n a m e ∣ 年 龄 : name|年龄: name∣年龄:age|性别: s e x ∣ 最 喜 欢 的 明 星 : sex|最喜欢的明星: sex∣最喜欢的明星:favoriteStar"
}
class Bird2(var sex: String) extends Animal {
var flyHigh: Double = _
def this(name: String,age: Int,sex: String) = {
this(sex)
this.name = name
this.age = age
}
def this(name: String,age: Int,sex: String,flyHigh: Double) = {
this(name,age,sex)
this.flyHigh = flyHigh
}
def birdMethod: Unit = {
println(“Bird类:”+this.getClass)
}
override def action: String = s"喜欢翱翔、高飞、叽叽喳喳…"
override def toString = s"姓名: n a m e ∣ 年 龄 : name|年龄: name∣年龄:age|性别: s e x ∣ 飞 翔 高 度 : sex|飞翔高度: sex∣飞翔高度:flyHigh"
}
object ExtendsDemo2 {
def main(args: Array[String]): Unit = {
val persion = new Persion2(“郭敬明”,30,“male”,“杨幂”)
val bird = new Bird2(“白鹭”,2,“female”,999)
val buffer: ListBuffer[Animal] = new ListBuffer[Animal]
buffer += (persion,bird)
println(buffer)
println(classOf[Persion2])
println(classOf[Bird2])
instanceOfMethod1(buffer(Random.nextInt(buffer.length)))
instanceOfMethod2(buffer(Random.nextInt(buffer.length)))
}
//判断一个类是否为指定类及其子类对象。该方法不能精确判断
def instanceOfMethod1(animal: Animal) = {
if(animal.isInstanceOf[Persion2]) {
val persion = animal.asInstanceOf[Persion2]
persion.persionMethod
} else if (animal.isInstanceOf[Bird2]) {
val bird = animal.asInstanceOf[Bird2]
bird.birdMethod
} else {
println(“其他类型”)
}
}
//可以精确判断
def instanceOfMethod2(animal: Animal) = {
if (animal.getClass == classOf[Persion2]) {
val persion = animal.asInstanceOf[Persion2]
persion.persionMethod
} else if (animal.getClass == classOf[Bird2]) {
val bird = animal.asInstanceOf[Bird2]
bird.birdMethod
} else {
println(“其他类型”)
}
}
}
7.8 样例类
case class Teacher(name: String, age: Int)
case class Student(name: String, age: Int)
object Stranger
object CaseClassTest {
def main(args: Array[String]): Unit = {
val teacher1 = Teacher(“张三”,33)
val teacher2 = Teacher(“李四”,26)
val student1 = Student("小明",9)
val student2 = Student("小红",19)
val stranger1 = Stranger
val arr = Array(teacher1,teacher2,student1,student2,stranger1)
for (person <- arr) {
println(matchCase(person))
}
}
def matchCase(person: AnyRef) = {
person match {
case Teacher(name,age) => s"name= n a m e ∣ a g e = name|age= name∣age=age 允许教师进入…"
case Student(name,age) => {
if (age < 18)
s"name= n a m e ∣ a g e = name|age= name∣age=age 允许未成年学生进入…"
else
s"name= n a m e ∣ a g e = name|age= name∣age=age 允许成年学生进入…"
}
case Stranger => s"禁止陌生人进入!!!"
case _ => s"错误类型匹配!!!"
}
}
}
说明:
case类是一种特殊的类,它们经过优化以被用于模式匹配
当定义一个类时,如果在class关键字前加上case关键字,则该类称为case类
Scala为case类自动重载了许多实用的方法,包括toString、equals和hashcode方法
Scala为每一个case类自动生成一个伴生对象,其包括模板代码1个apply方法,因此,实例化case类的时候无需使用new关键字。和1个unapply方法,该方法包括一个类型为伴生类的参数返回的结果是Option类型,对应的类型参数是N元组,N是伴生类中主构造器参数的个数。Unapply方法用于对对象进行解构操作,在case类模式匹配中,该方法被自动调用,并将待匹配的对象作为参数传递给它。
7.9 特质
trait UsbDisk {
var usbDiskType: String
def usbFunc: String
}
trait Mouse {
var mouseType: String
def mouseFunc: String
}
abstract class Computer {
var brand: String
var price: String
var madeIn: String
def permitGames: String
}
class ThinkPad(var optionSystem: String) extends Computer with UsbDisk with Mouse {
override var brand: String = _
override var price: String = _
override var madeIn: String = _
override var usbDiskType: String = _
override var mouseType: String = _
def this(brand: String,price: String,madeIn: String,os: String) = {
this(os)
this.brand = brand
this.price = price
this.madeIn = madeIn
this.optionSystem = os
}
def this(brand: String,price: String,madeIn: String,os: String,usbDiskType: String) = {
this(brand,price,madeIn,os)
this.usbDiskType = usbDiskType
}
def this(brand: String,price: String,madeIn: String,os: String,usbDiskType: String,mouseType: String) = {
this(brand,price,madeIn,os,usbDiskType)
this.mouseType = mouseType
}
override def permitGames: String = s"绝地求生、英雄联盟、炉石传说…"
override def usbFunc: String = s"U盘用来备份游戏数据…"
override def mouseFunc: String = s"鼠标用来操作人物的移动方向…"
override def toString: String = s"[{电脑|品牌: b r a n d , 产 地 : brand, 产地: brand,产地:madeIn, 操作系统: o p t i o n S y s t e m , 价 格 : optionSystem, 价格: optionSystem,价格:price},{U盘|类型:KaTeX parse error: Expected 'EOF', got '}' at position 12: usbDiskType}̲,{鼠标|类型:mouseType}]"
}
object ExtendsDemo3 {
def main(args: Array[String]): Unit = {
val computer1 = new ThinkPad(“thinkPadE480”,“6666RMB”,“China”,“Win10”)
val computer2 = new ThinkPad(“thinkPadE480”,“6666RMB”,“China”,“Win10”,“西部数据”,“罗技”)
println(computer1)
println(computer2)
println(computer2.permitGames)
println(computer2.usbFunc)
println(computer2.mouseFunc)
}
}
说明:
定义关键字trait。特质类似于java中的接口,java中实现接口关键字"implements",scala中使用"with",如class A extends classB with traitC with traitD …
7.10 抽象类
package scalaDemo.abstractDemo.Demo01
abstract class Animal01 {
var name: String //抽象属性
var sex: String
val name2 = "Animal01" //普通属性
def describ(): String //抽象方法
def action() //抽象方法
/**
* @Author: qwerdf@QAQ
* @Description:
* 总结:
* 抽象类不能被实例化,可以通过创建匿名子类对象来实现
* 抽象类不一定有abstract方法,但是含有抽象方法或抽象属性的一定是抽象类
* scala中抽象方法不能用abstract标记,定义方式:def temp()
* 如果一个类继承了抽象类,则必须实现抽象类的所以抽象方法和抽象属性,除非它自己也声明为abstract类
* 抽象方法和抽象属性不能使用private、final来修饰,因为这些关键字都是和重写/实现相违背的
* 抽象类可以有实现的方法
* 子类重写抽象方法不需要override,也可以加上
* @Date: 2021/3/14
* @Param null:
* @return: null
**/
}
package scalaDemo.abstractDemo.Demo01
object AnimalTest01 {
def main(args: Array[String]): Unit = {
//临时创建一个匿名子类
val dog = new Animal01 {
override var name: String = "dog"
override var sex: String = "雌性"
override def describ(): String = {
s"name: $name\nsex: $sex"
}
override def action(): Unit = {
println("正在追赶小偷...")
}
}
val cat = new Animal01 {
override var name: String = "cat"
override var sex: String = "雄性"
override def describ(): String = {
s"name: $name\nsex: $sex"
}
override def action(): Unit = {
println("正在抓老鼠...")
}
}
println(dog.describ())
dog.action()
println(cat.describ())
cat.action()
}
}
8.方法和函数
import scala.collection.mutable
import scala.collection.mutable.{ArrayBuffer, ListBuffer}
object FuncAndMethod {
def main(args: Array[String]): Unit = {
//定义一个函数
val fun1: (Int,Int) => Int = (x,y) => x + y
val fun2 = (x:Int, y:Int) => x + y
val fun2_2 = (x: Int) => x //入参只有一个时,括号不能少
val fun3: () => String = () => “飞雪连天射白鹿”
println(fun3()) //参数列表为空时,调用fun3()括号不能省略
method5(999999999) //方法中参数列表为空可以省略括号
method2("笑书神侠倚碧鸳")
val hmap = new mutable.HashMap[String,ArrayBuffer[String]]()
val buffer1 = ArrayBuffer[String]()
val buffer2 = ArrayBuffer[String]()
buffer1 += "飞狐外传"
buffer1 += "飞狐外传"
buffer1 += "雪山飞狐"
buffer1 += "连城诀"
buffer1 += "天龙八部"
buffer1 += "射雕英雄传"
buffer1 += "白马啸西风"
buffer1 += "鹿鼎记"
buffer1 += "笑傲江湖"
buffer1 += "书剑恩仇录"
buffer1 += "神雕侠侣"
buffer1 += "侠客行"
buffer1 += "倚天剑"
buffer1 += "碧血剑"
buffer1 += "鸳鸯刀"
buffer2 += ("武林外史","绝代双骄","楚留香传奇","多情剑客无情剑","萧十一郎","流星蝴蝶剑","边城浪子",
"陆小凤传奇","孔雀翎","天涯明月刀","三少爷的剑","圆月弯刀","小李飞刀","浣花洗剑录")
hmap += ("金庸" -> buffer1,("古龙",buffer2))
println(hmap)
val res1 = method3("神雕侠侣",hmap)
val res2 = method3("流星蝴蝶剑",hmap)
val res3 = method3("三国演义",hmap)
println(res1)
println(res2)
println(res3)
val res4 = method4("小李飞刀",hmap,fun4)
val res5 = method4("神雕侠侣",hmap,fun4)
val res6 = method4("西游记",hmap,fun4)
println(res4)
println(res5)
println(res6)
val grep1: ArrayBuffer[String] = grep(buffer1)
println(grep1)
//for过滤器函数
val grepFunc = (books: ArrayBuffer[String], grepPattern: String) => {
if (books != null) {
val greps: ArrayBuffer[String] = for {
book <- books
if (book.contains(grepPattern))
} yield book
println(greps)
}
}
grepFunc(buffer1,"剑")
}
//for过滤器方法
def grep(books: ArrayBuffer[String]): ArrayBuffer[String] = {
var greps: ArrayBuffer[String] = null
if (books != null) {
greps = for {
book <- books
if (book.length == 3)
} yield book
}
greps
}
//定义一个方法
def method1(x:Int,y:Int): Int = {
x + y
}
def method2(str: String): Unit = {
if (!str.isEmpty && str != null) {
println(str)
}
}
def method3(bookName: String, bookStore: mutable.Map[String,ArrayBuffer[String]]): String = {
var tmp_author: String = “未知作者”
if (!bookName.isEmpty || bookName != null) {
for (map <- bookStore) {
val author = map._1
val bookArray = map._2
if (bookArray.contains(bookName)) {
tmp_author=author
}
}
}
tmp_author
}
def method4(bookName: String, bookStore: mutable.Map[String,ArrayBuffer[String]],fun: (String, mutable.Map[String,ArrayBuffer[String]]) => String) : String = {
val value = fun(bookName,bookStore)
value
}
val fun4: (String,mutable.Map[String,ArrayBuffer[String]]) => String = (bookName,bookStore) => {
var tmp_author: String = “未知作者”
if (!bookName.isEmpty || bookName != null) {
for (map <- bookStore) {
val author = map._1
val bookArray = map._2
if (bookArray.contains(bookName)) {
tmp_author=author
}
}
}
tmp_author
}
def method5(f: => Int) = {
println(f)
}
}
9.偏函数
object PartialFunc {
def main(args: Array[String]): Unit = {
val array = Array(‘a’,5,2f,1314D,false,“偏函数”)
for (arr <- array) {
println(matchCase(arr))
println(partitionFunc(arr))
}
}
def matchCase(element: Any) = {
element match {
case a: Char => s"char类型 a " c a s e a : I n t = > s " i n t 类 型 a" case a: Int => s"int类型 a"casea:Int=>s"int类型a"
case a: Long => s"Long类型 a " c a s e a : F l o a t = > s " f l o a t 类 型 a" case a: Float => s"float类型 a"casea:Float=>s"float类型a"
case a: Double => s"double类型 a " c a s e a : B o o l e a n = > s " 布 尔 类 型 a" case a: Boolean => s"布尔类型 a"casea:Boolean=>s"布尔类型a"
case b: String => s"string类型$b"
case _ => s"未匹配到…"
}
}
//偏函数定义
def partitionFunc: PartialFunction[Any, String] = {
case a: Char => s"char类型 a " c a s e a : I n t = > s " i n t 类 型 a" case a: Int => s"int类型 a"casea:Int=>s"int类型a"
case a: Long => s"Long类型 a " c a s e a : F l o a t = > s " f l o a t 类 型 a" case a: Float => s"float类型 a"casea:Float=>s"float类型a"
case a: Double => s"double类型 a " c a s e a : B o o l e a n = > s " 布 尔 类 型 a" case a: Boolean => s"布尔类型 a"casea:Boolean=>s"布尔类型a"
case b: String => s"string类型$b"
case _ => s"未匹配到…"
}
}
说明:
没有match匹配的一组case语句,常用于输入模式匹配。
PartialFunction[A,B] —A表示输入类型,B表示输出类型
10.泛型(方法、类)
abstract class Persion4 {
var name: String
var age: Int
def work: Unit
}
class Teacher4(var salary: Double) extends Persion4 {
override var name: String = _
override var age: Int = _
def this(salary: Double, name: String, age: Int) = {
this(salary)
this.name = name
this.age = age
}
override def work: Unit = println(“教书育人…”)
def getTeacherInfo: String = {
s"姓名: n a m e 年 龄 : name 年龄: name年龄:age 工资:$salary"
}
override def toString = s"Teacher($name, $age, $salary)"
}
//类添加泛型
class Student4[T] (var chineseScore: T, var mathScore: T, var englishScore: T, var comprehensiveScore: T) extends Persion4 {
override var name: String = _
override var age: Int = _
def this(name: String, age: Int, chinese: T, math: T, english: T, comprehensive: T) = {
this(chinese,math,english,comprehensive)
this.name = name
this.age = age
}
override def work: Unit = println(“遨游知识的海洋,为中华崛起而奋斗…”)
def getStudentInfo: String = {
s"姓名: n a m e 年 龄 : name 年龄: name年龄:age 成绩:[ c h i n e s e S c o r e , chineseScore, chineseScore,mathScore, e n g l i s h S c o r e , englishScore, englishScore,comprehensiveScore]"
}
override def toString = s"Student($name, $age, c h i n e s e S c o r e , chineseScore, chineseScore,mathScore, e n g l i s h S c o r e , englishScore, englishScore,comprehensiveScore)"
}
object GenericType {
def main(args: Array[String]): Unit = {
val student1 = new Student4Int
val teacher1 = new Teacher4(6666D,“小马哥”,27)
val arr = Array(student1,teacher1)
for (per <- arr) {
val info = getInfo(per)
println(info)
}
}
//方法添加泛型
def getInfo[T](persion: T): String = {
if (persion.getClass == classOf[Student4[Int]]) {
val student = persion.asInstanceOf[Student4[Int]]
student.getStudentInfo
} else if (persion.getClass == classOf[Teacher4]) {
val teacher = persion.asInstanceOf[Teacher4]
teacher.getTeacherInfo
} else s"其他类型…"
}
}
11.上边界和下边界
abstract class ElecGoods {
var categary: String
var brand: String
var model: String
def function: String
}
class Pad extends ElecGoods {
var madeIn: String = _
override var categary: String = _
override var brand: String = _
override var model: String = _
def this(madeIn: String, categary: String, brand: String, model: String) = {
this()
this.categary = categary
this.brand = brand
this.model = model
this.madeIn = madeIn
}
override def function: String = {
s"电影、听音乐、玩游戏…"
}
override def toString = s"Phone($categary, $brand, $model, $madeIn)"
}
class Phone extends ElecGoods {
var madeIn: String = _
override var categary: String = _
override var brand: String = _
override var model: String = _
def this(madeIn: String, categary: String, brand: String, model: String) = {
this()
this.categary = categary
this.brand = brand
this.model = model
}
override def function: String = {
s"通话、听音乐、玩游戏…"
}
override def toString = s"Phone($categary, $brand, $model, $madeIn)"
}
class HuaWeiPhone(var detailModel: String) extends Phone {
private var price: Double = _
def this(categary: String, brand: String, model: String, madeIn: String, detailModel: String) = {
this(detailModel)
this.categary = categary
this.brand = brand
this.model = model
this.madeIn = madeIn
}
def this(categary: String, brand: String, model: String, madeIn: String, detailModel: String, price: Double) = {
this(categary,brand,model,madeIn,detailModel)
this.price = price
}
override def toString = s"HuaWeiPhone($categary, $brand, $model, $madeIn, $detailModel, $price)"
}
class Iphone(var detailModel: String) extends Phone {
private var price: Double = _
def this(categary: String, brand: String, model: String, madeIn: String, detailModel: String) = {
this(detailModel)
this.categary = categary
this.brand = brand
this.model = model
this.madeIn = madeIn
}
def this(categary: String, brand: String, model: String, madeIn: String, detailModel: String, price: Double) = {
this(categary,brand,model,madeIn,detailModel)
this.price = price
}
override def toString = s"Iphone($categary, $brand, $model, $madeIn, $detailModel, $price)"
}
object BoundType {
def main(args: Array[String]): Unit = {
val pad = new Pad(“USA”,“平板电脑”,“苹果”,“ipad”)
val phone = new Phone(“China”,“5G手机”,“华为”,“Mate30”)
val huaWeiPhone = new HuaWeiPhone(“5G手机”,“华为”,“Mate30”,“China”,“Mate30_Pro_8G”,6399)
val iphone = new Iphone(“5G手机”,“苹果”,“iphoneSE”,“USA”,“iphoneSE2_4G”,2799)
upBoundMethod[Phone](huaWeiPhone)
upBoundMethod[Phone](iphone)
//upBoundMethod[Phone](pad) //编译提示:方法入参类型不匹配,应该为泛型Phone的类型或者子类
//upBoundMethod[ElecGoods](phone) //泛型错误,当前上边界值为Phone类型,泛型A应该为Phone类、HuaWeiPhone类、Iphone类
downBoundMethod[Phone](huaWeiPhone)
downBoundMethod[Phone](iphone)
// downBoundMethodPhone //编译提示:方法入参类型不匹配,应该为泛型Phone的类型或者子类
downBoundMethodHuaWeiPhone //泛型错误,当前下边界值为Phone类型,泛型B应该为Phone类、ElecGoods类
}
//上边界 A类型为Phone类及其子类,而该方法入参类型为A类型及其A类型的子类对象
def upBoundMethod [A <: Phone] (elecGoods: A): Unit = {
if (elecGoods.getClass == classOf[HuaWeiPhone]) {
val huaWeiPhone = elecGoods.asInstanceOf[HuaWeiPhone]
println(huaWeiPhone)
} else if (elecGoods.getClass == classOf[Iphone]) {
val iphone = elecGoods.asInstanceOf[Iphone]
println(iphone)
}
}
//下边界 B类型为Phone类及其父类,而该方法入参类型为B类型及其B类型的子类对象,因为B类型的子类不仅仅只有Phone一个
def downBoundMethod[B >: Phone](elecGoods: B): Unit = {
if (elecGoods.isInstanceOf[Phone]) {
val phone = elecGoods.asInstanceOf[Phone]
println(phone)
}
}
}
12.隐式转换之参数、方法、类
12.1隐式参数
package scalaDemo.implicitDemo.demo01
object ImplicitValDemo01 {
implicit val name = "tom"
implicit val age = 18
def main(args: Array[String]): Unit = {
implicitFun01
implicitFun02("sunny")
implicitFun03//运行报错
}
def implicitFun01(implicit name: String = "jack") = {
println(s"fun01:my name is $name")
}
def implicitFun02(implicit name: String = "jack") = {
println(s"fun01:my name is $name")
}
def implicitFun03(implicit score: Double) = {
println(s"fun01:my score is $score")
}
/**
* @Author: qwerdf@QAQ
* @Description:
* 总结:
* 1.隐式值优先级:传值 > 隐式值 > 默认值
* 2.隐式值匹配时不能有二义性
* 3.如果调用方法时,传值、隐式值、默认值都没有,程序会报错
* @Date: 2021/3/14
* @Param null:
* @return: null
**/
}
12.2隐式方法
object ImplictTransformationFunc {
def main(args: Array[String]): Unit = {
import CurrencyTypeTransformArea._
val rmb = new RMB()
//寻找隐式区域,调用隐式方法并将rmb作为参数传入获取CurrencyType对象,即currencyTypeTransform(rmb).toRMB
val rmbInfo = rmb.toRMB(520)
println(rmbInfo)
val dollar = new Dollar()
val dollarInfo = dollar.toDollar(520)
println(dollarInfo)
}
}
//隐式区域
object CurrencyTypeTransformArea {
implicit def currencyTypeTransform(currencyType: Currency): CurrencyType = {
new CurrencyType
}
}
class CurrencyType {
def toRMB(price: Double): RMB = {
RMB(price)
}
def toDollar(price: Double): Dollar = {
Dollar(price)
}
}
class Currency {}
class RMB extends Currency {
var price: Double = _
private val logo: String = “RMB”
def this(price: Double) = {
this()
this.price = price
}
override def toString = s" p r i c e price pricelogo"
}
object RMB {
def apply(price: Double): RMB = new RMB(price)
}
class Dollar extends Currency {
var price: Double = _
private val logo: String = “$”
def this(price: Double) = {
this()
this.price = price
}
override def toString = s" p r i c e price pricelogo"
}
object Dollar {
def apply(price: Double): Dollar = new Dollar(price)
}
12.3隐式类
package scalaDemo.implicitDemo.demo02
object ImplicitClassDemo01 {
implicit class DataBaseFun01(val mySql: Mysql) {
def insert(): String = {
s"insert..."
}
}
def main(args: Array[String]): Unit = {
val mysql = new Mysql
println(mysql.insert())
}
}
class Mysql {
val dname: String = "mysql"
def dbState = {
s"mysql is running..."
}
/**
* @Author: qwerdf@QAQ
* @Description:
* 总结:
* 1.隐式类的构造参数有且只能有一个
* 2.隐式类必须定义在类、伴生对象、包对象里面,不能是顶级的objects
* 3.隐式类不能是case class
* 4.作用域内不能有同名标识符,否则编译器无法识别
* @Date: 2021/3/14
* @Param null:
* @return: null
**/
}
需要一个主构造器,且参数只能有一个;
隐式类必须定义在类或伴生对象中…
object ImplictTransformationFunc {
//隐式类
implicit class CurrencyType2(var currency: Currency) {
def toRMB(price: Double): RMB = {
RMB(price)
}
def toDollar(price: Double): Dollar = {
Dollar(price)
}
}
def main(args: Array[String]): Unit = {
//方式1:隐式方法测试
// import CurrencyTypeTransformArea._ //导入隐式方法区域
// val rmb = new RMB()
// //寻找隐式区域,调用隐式方法并将rmb作为参数传入获取CurrencyType对象,即currencyTypeTransform(rmb).toRMB
// val rmbInfo = rmb.toRMB(520)
// println(rmbInfo)
//方式2:隐式类测试
val dollar = new Dollar()
//寻找隐式类,然后将dollar作为构造器参数进行实例化,即CurrencyType2(dollar).toDollar
val dollarInfo = dollar.toDollar(1314)
println(dollarInfo)
}
}
//隐式区域
object CurrencyTypeTransformArea {
implicit def currencyTypeTransform(currencyType: Currency): CurrencyType = {
new CurrencyType
}
}
class CurrencyType {
def toRMB(price: Double): RMB = {
RMB(price)
}
def toDollar(price: Double): Dollar = {
Dollar(price)
}
}
class Currency {}
class RMB extends Currency {
var price: Double = _
private val logo: String = “RMB”
def this(price: Double) = {
this()
this.price = price
}
override def toString = s" p r i c e price pricelogo"
}
object RMB {
def apply(price: Double): RMB = new RMB(price)
}
class Dollar extends Currency {
var price: Double = _
private val logo: String = “$”
def this(price: Double) = {
this()
this.price = price
}
override def toString = s" p r i c e price pricelogo"
}
object Dollar {
def apply(price: Double): Dollar = new Dollar(price)
}
隐式转换场景:
当方法中的参数类型与目标类型不一致时候,如:
def method1(age: Int) = {}
method1(66.5) //传入类型不匹配,要想编译通过,可使用隐式转换。
当对象调用所在类中没有该方法或成员时,编译器会自动将对象进行隐式转换,转变为含有该方法或成员的实例。
13.Unit、Null、Nothing类型
13.1 Null类
Null类只有一个实例对象null,类似于java中的null引用,null可以赋值给任意引用类型AnyRef,但是不能赋值给值类型AnyVal
13.2 Unit类
Unit类型用来标识过程,也就是没用明确返回值的函数,类似于java里的void。Unit类只有一个实例(),没有实质意义。
def sayOk(): Unit = {
println(“ok”)
}
13.3 Nothing类
Nothing类可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回。该类是其他任意类型的子类,可以跟要求返回值的方法兼容。
def test() : Nothing = {
throw new Exception()
}
14.递归
package scalaDemo
object Fibnacci {
def main(args: Array[String]): Unit = {
println(fibn(7))
}
/**
* @Author: qwerdf@QAQ
* @Description: 斐波那契数列数列从第3项开始,每一项都等于前两项之和
* 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597 ...
* 示例: n=7 输出13
* 第1次入栈:main栈 println(fibn(7)) 最后输出:13
* 第2次 fibn1栈 fibn(7) fibn(n - 2) + fibn(n - 1) 返回9:5 + 8 = 13
* 第3次 fibn(n - 2) = fibn(5) 返回值8: 5
* fibn(n - 1) = fibn(6) 返回值7: 8
* 第4次 fibn(5 - 2) + fibn(5 - 1) = fibn(3) + fibn(4) 返回值6:2+3=5
* fibn(6 - 2) + fibn(6 - 1) = fibn(4) + fibn(5) 返回值5:3+5=8
* 第5次 f(1) + f(2) = 2
* f(2) + f(3) = 1 + f(3) 返回值4:1+2=3
* f(2) + f(3) = 1 + f(3) 返回值3:1+2=3
* f(3) + f(4) 返回值1:2+3=5
*第6次 f(1) + f(2) = 2
* f(1) + f(2) = 2
* f(1) + f(2) = 2
* f(2) + f(3) = 1 + f(3) 返回值1:1+2=3
*第7次 f(1) + f(2) = 2
*
*备注:先入栈则后出栈
*
* @Date: 2022/4/23
* @Param null:
* @return: null
**/
//递归函数编译阶段无法推断具体的结果类型,必须指定返回值类型
val fibn: Int => Int = n => {
if (n == 1 || n == 2) {
1
} else {
fibn(n - 2) + fibn(n - 1)
}
}
}
15.异常处理
package scalaDemo
import com.sun.xml.internal.bind.v2.TODO
object TryCatch {
def main(args: Array[String]): Unit = {
/**
* @Author: qwerdf@QAQ
* @Description: 将可能发生异常的代码封装在try块中,catch块用来捕获异常并处理,避免程序异常中止
* 1.在scala中只有一个catch,在java中可以有多个
* 2.在catch中有多个case,每个case匹配一种异常,即模式匹配思想。
* @Date: 2022/4/24
* @Param args:
* @return: void
**/
try {
val num = 9 / 0
} catch {
case ex: ArithmeticException => {
//TODO 捕获异常,处理业务逻辑
println("捕获了除数为零的算术异常")
}
case ex: Exception => {
//TODO 捕获异常,处理业务逻辑
println("捕获了异常")
}
} finally {
//TODO 有无异常都会执行的代码块,一般用于关闭数据库连接、IO流等
println("执行finally代码块...")
}
println("程序继续执行...")
}
}