数据类型
scala的基本数据类型一般是从java中引用过来的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UQhDchJn-1689507716358)(E:\Typora\16.png)]
运算符
==
在Java中==号如果对字符串比较那么比较的就是内存地址
在Scala中–号比较的是字符串内容(eq是比较内存地址)
val str1: String = new String("str")
val str2: String = new String("str")
println(str1 == str2) //true
这个==直接调用了Java的equals方法
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
逻辑运算符
Scala中的逻辑运算符和Java一样
实例
if (i > 1 && j < 4){
}
位运算符
&
按位与:有0就是0都是1的时候才是1
println(5 & 4) // 4
5: 0101
4: 0100
========
0100
|
按位或:有1就是1
println(5 | 4)// 5
5: 0101
4: 0100
=======
0101
%
取模运算:除后余下的数
println(5 % 4)// 1
流程控制
if else
为true就执行为false就执行else
val i = "str"
if(i == "str"){
println("条件成立")
}else{
println("条件不成立")
}
在Scala中这些流程语句都是有返回值的(返回值不是Any就是Unit)
因为流程判断要在运行时才可以判断完成所以在编译阶段程序无法识别返回值为什么类型所以返回Any
如果指定了返回类型那么在编译阶段就可以识别
val i = "str"
val f = if (i == "str") {
666
} else {
"啊吧啊吧"
}
println(f)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bSqSZU3m-1689507716358)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230701160303953.png)]
for
基本循环
val str = 1 to 5 //从一到五(包括五)
val str2 = 1 until 5 //从一到五(不包括五)
for(i <- str){
print(i)
}
println()
for(i <- str2){
print(i)
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tX7kYKjX-1689507716359)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230701163021760.png)]
遍历集合
val arr = Range(1,5,1) //Range表示集合 1到4 步长为1
for(i <- arr){
print(i) //i表示arr集合中所以元素
}
循环守卫
val arr = Range(1, 5) //Range表示集合 1到4
for (i <- arr if i % 2 == 0) { //满足if条件就执行不满足就不执行
print(i)
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VR0moLKX-1689507716359)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230701163502759.png)]
循环步长
步长表示每次执行移动的长度(默认为1)
val arr = 1 to 5 by 2 //表示从1到5(包括5)步长为2
for (i <- arr) {
println(i)
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8HZlSYAu-1689507716360)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230701163756573.png)]
循环嵌套
for (i <- 1 to 9; j <- 1 to i) {
if (i != j) {
print(i + "*" + j + "=" + i * j+"\t")
}else {
println(i + "*" + j + "=" + i * j)
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-INi1RXyz-1689507716360)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230701164524269.png)]
返回值
val result = for(i <- 1 to 3) yield {
i
}
println(result)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GWPxNXcO-1689507716360)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230701165159142.png)]
while
基本循环
while (true){//死循环
println("666")
}
do while
先执行再判断
do{
println("sss")
}while(false)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WVFrYJMe-1689507716361)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230701165645549.png)]
中断循环
在Scala中没有像Java中的contion和break关键字
for (i <- 0 to 5) {
if (i == 3) {
return
}
println(i)
}
函数式编程
函数声明和使用
使用def关键字定义函数(函数可以声明在任何位置)
def pr(): Unit = {
println("函数调用")
}
pr()
可变参数
注意:可变参数要放到最后因为程序不能识别什么时候可变参数停所以只能在最后并且只有一个可变参数
object test {
def main(args: Array[String]): Unit = {
sum(1,2,3,4,5,6)
}
def sum(i: Int*): Unit = {//在这里面i为集合
var count = 0
i.foreach(data => count += data)
println(count)
}
}
参数默认值
使用=赋值实现默认值
def test(name: String, Password: String = "000000"): Unit = {
println(s"账号:$name,密码:$Password")
}
test("吴彦祖")
带名参数
def test(name: String, Password: String = "000000"): Unit = {
println(s"账号:$name,密码:$Password")
}
test(Password = "123123",name = "吴彦祖")
匿名函数
在这个案例中sss相对于给这匿名函数付了名
val sss = () => "666"
println(sss())
函数对象
访问函数本身
使用_特殊符号来指定调用
def sss() = "666"
println(sss _)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RsI6CZ6w-1689507716361)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230702101655282.png)]
函数类型
def sss() = "666"
//Function0[String]
//类型中的0表示函数参数中的个数
//[]中的String表示返回值
val f:Function0[String] = sss _ //将函数sss的对象赋值为f
函数参数
def test(f: () => String): String = {
f()
}
def f() = "调用f"
test(f)
函数返回函数
def outer()={
def inner={
println("inner")
}
inner _
}
val in = outer()
in()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DbUBwZkU-1689507716361)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230702142552605.png)]
def outer(x: Int) = {
def inner(y: Int) = {
x + y
}
inner _
}
println(outer(1)(2)) //第一层表示outer函数的参数 第二层表示inner的参数
控制抽象
def test(f: => Unit): Unit = {//不完整的(抽象)
f
}
test(println("控制抽象"))
函数柯里化(语法)
在下列这段代码中使用def创建了一个函数,这里存在一个问题x参数和y参数互不影响但是在调用函数时必须传入2个值
def test(x: Int, y: Int): Unit = {
for (i <- 1 to x){
println(i)
}
for (i <- 1 to y) {
println(i)
}
}
test(12,45)
柯里化
def test(x: Int)(y: Int): Unit = {
for (i <- 1 to x) {
println(i)
}
for (i <- 1 to y) {
println(i)
}
}
val f: Int => Unit = test(10)
f(1)
递归
函数自己调用自己就是递归
注意:不能省略返回值类型 方法执行时如果压栈的内存超了就会报错
def test(i: Int): Int = {
if (i == 1) {
1
} else {
i * test(i - 1)
}
}
println(test(5))
惰性函数lazy
惰性:只有在使用时才会调用创建
def test(i: Int): Int = {
if (i == 1) {
1
} else {
i * test(i - 1)
}
}
lazy val i = test(5)
println(i)
面向对象
创建类
使用class关键字来定义类
注意:在类中定义的变量需要显示的指定类型,因为编译器并不能知道变量被赋什么类型的值所以就会报错
在编译器编译后会把var属性生成get和set方法把val只生成get方法
当调用对象的变量时就相当于调用了get方法当所以=赋值时相当于调用了set方法
object test {
def main(args: Array[String]): Unit = {
val user = new User
println(user.name)
}
class User {
var name: String = "zhangsan"
}
}
权限
java
private : 私有的 同类才能访问
default : 包权限 同类 同包访问
protected : 受保护权限 同类 同包 子类访问
public : 公共的 所有类
scala
default : 公共的,任何地方都可以使用
private[包名] : 包私有 同类 同包
protected : 受保护的 同类 子类
方法
方法其实就是函数不过多了一些约束
重载
object test {
def main(args: Array[String]): Unit = {
test("String")
test(1)
}
def test(str: String): Unit = {
println(str)
}
def test(i: Int): Unit = {
println(i)
}
}
单例对象
使用object关键字
object test {
def main(args: Array[String]): Unit = {
val t = test.apply()
}
class test{
}
object test{
def apply():test = new test
}
}
构造方法
object test {
def main(args: Array[String]): Unit = {
new User()
}
//在scala中声明类就是声明函数
class User() {
println("构造方法")
}
}
辅助构造方法
在主构造方法中使用def关键字定义
在辅助构造方法中必须(直接或者间接)调用主构造方法可以使用this()调用
object test {
def main(args: Array[String]): Unit = {
new User("吴彦祖")
}
//在scala中声明类就是声明函数
class User() {
println("构造方法")
def this(name: String) {
this()
println(name)
}
}
}
继承
使用extends继承类可以继承父类的方法和属性
object test {
def main(args: Array[String]): Unit = {
val b = new B
b.testa()
}
class A {
def testa(): Unit = {
println("A方法")
}
}
class B extends A {
}
}
抽象
使用abstract定义抽象类
子类必须重写抽象类的抽象方法
object test {
def main(args: Array[String]): Unit = {
println(new User2("吴彦祖").testu())
}
abstract class User {
def testu(): String
}
class User2(name: String) extends User {
def testu(): String = {
name
}
}
}
抽象属性
object test {
def main(args: Array[String]): Unit = {
println(new ttt("吴彦祖").name)
}
abstract class User {
var name: String
}
class ttt(name1: String) extends User {
var name: String = name1
}
}
特质
无父类
无父类直接使用extends混入特质
如果要混入多个特质就需要使用with关键字
trait Run {
def run(): Unit
}
class Cat extends Run {
override def run(): Unit = {
println("特质")
}
}
有父类
在extends后面使用with
class A {
}
trait Run {
def run(): Unit
}
class Cat extends A with Run {
override def run(): Unit = {
println("特质")
}
}
扩展
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-680MKLDt-1689507716362)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230703144533361.png)]
集合
在scala中默认使用的是不可变集合(不需要导包)scala.collection.immutable
可变集合存在scala.collection.mutable包下如果要使用那么必须导包
数组
Array不可变
Array是一个不可变数组
//创建了一个长度为6类型为String的数组
val arr = new Array[String](6)
arr.update(0, "吴彦祖")
arr(1) = "彭于晏"
println(arr.mkString(","))
for (i <- arr){
println(i)
}
arr.foreach(print)
arr.clone() //创建副本
使用apply创键
//创建数组
val arr = Array.apply(1,2,3,4,5,6,7,8,9,10)
在下列代码中使用+:添加数据后就会形成一个新的Array数组所以在下面打印只能打印出1,2,34
val arr = Array(1, 2, 3, 4)
val arr2 = arr.+:(12)//添加到数组前面
val arrr3 = arr.:+(5)//添加到数组后面
println(arr.mkString(","))
ArrayBuffer可变数组
//创建
val arr = new ArrayBuffer[Int]()//可变
val arr1 = Array(4,5,6)//不可变
//增加
arr.append(1,2,3)
arr.appendAll(arr1)//在后面追加数组数据
arr.insert(0,5)//在指定位置插入元素
arr.insertAll(1,arr1)//在指定索引插入数组
//修改
arr.update(3,6)//修改指定索引的元素
arr.updated(2,10)//修改指定索引的元素(并且创建新数组)
//删除
arr.remove(0)//删除0索引的元素
arr.remove(0,3)//从0索引位置开始删除3个元素
Seq
seq是一个有序,数据可重复的数据集合
不可变Seq
//创建因为seq是一个特质所以不能所以new创建
val seq = Seq.apply(1, 2, 3, 4, 5)
val ints = seq.+:(1)
println(seq)
println(ints)
seq.++:(ints)//在前面插入集合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RSfN5Bn6-1689507716362)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230703164519727.png)]
可变
val buffer = ListBuffer(1, 2, 3, 4, 5, 6)
buffer.append(12) //添加
buffer.remove(2) //删除
buffer.updated(1,2)//修改指定索引的元素
buffer.clear()//清空
Set
set集合是一个无序且数据不可重复
不可变
set在创建时会
//创建
val set = Set(1,2,3,4,5,6,7,8)
可变
val set = mutable.Set(1, 2, 3, 4, 1, 5, 5, 3, 4)
set.add(1) //添加数据 因为set是无序所以不需要管添加位置
set.remove(2) //根据元素删除元素
Map
map集合是一个key-value键值对的集合无序
key不能重复如果重复会将原本的value覆盖
不可变
val map = Map(1 -> "121212", 2 -> "wqwqw")
println(map.contains(1)) //判断这个key在map中有没有
map.filter(k => k._1 == 1)//过滤如果key等于1就留下
map.get(1)//根据可以获取value
map.updated(1,"吴彦祖")//根据key修改value
可变
val map = mutable.Map("a" -> 111, "b" -> 222, "c" -> 333)
map.put("d",111)//添加,修改
map.get("a")//根据key获取value
map.remove("a")//根据key删除value和key
map.clear()//清空所以数据
map.keysIterator//key迭代器
map.valuesIterator//value迭代器
map.getOrElse("w", 0)//获取key为w的数据如果没有就返回0
元组
val y:(Int,String) = (1,"qqq")
val x:Tuple3[Int,String,Double] = (1,"qqq",1.0)
println(x._1)//直接所以_数字调用第几个元素
val tuple = x.copy()//复制
println(y.productElement(1))//查找1索引的元素
通用方法
val list = List(1, 2, 3, 4, 5, 6)
list.length//元素长度
list.isEmpty//判断集合是否为空
list.contains(3)//判断集合中是否有3这个元素
list.reverse//反转集合
list.distinct//集合去重 底层是使用HashSet实现
list.mkString(",")//将所有元素使用,分割开返回String
list.foreach(print)//循环遍历
val list = List(1, 2, 3, 4, 5, 6)
list.head //获取第一个元素
list.tail //获取除了第一个的元素
list.tails //相当于一直使用tail到最后一个
list.last //获取最后一个元素
list.init //获取除了最后一个的元素
list.inits //相当于一直使用init到最后一个(包含初始数组)
list.take(3)//取前3条数据
list.takeRight(3)//取后3条数据
list.drop(1)//删除前1个数据
list.dropRight(1)//删除后1个数据
val list = List(1, 2, 3, 4, 5, 6)
list.splitAt(2) //切分为2份集合
val iterator: Iterator[List[Int]] = list.sliding(2)//取2个数据默认步长为1 返回迭代器
while (iterator.hasNext) {//迭代
println(iterator.next())//获取值并先下滑动步长的距离
}
val list = List(1, 2, 3, 4, 5, 6)
val list2 = List(5, 6, 7, 8, 9)
list.intersect(list2)//交集 5,6
list.union(list2)//并集
list.diff(list2)//差集 1,2,3,4
list.zip(list2)//将集合中数据索引位置相同的放在一起 形成元组
功能函数
map
map中传入一个函数来实现功能
底层会使用while循环来遍历集合然后实现传入的功能
val list = List(1, 2, 3, 4, 5)
list.map(_ * 2)
扁平化
将集合中的元素拆分为个体的操作叫做扁平化
val list = List(List(1,2,3),List(2,3,4))
val flatten = list.flatten
println(flatten)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-drQ5lnIv-1689507716362)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230704094531512.png)]
flatMap将集合中的每条数据取出来实现自定义扁平化操作 返回List集合
val list = List("hello world", "hello scala")
println(list.flatMap(_.split(" ")))//List(hello, world, hello, scala)
过滤
按照指定的条件将集合中的数据就行筛选如果条件成立(true)就留下
val list = List(1, 2, 3, 4, 5, 6, 7)
println(list.filter(_ > 2))//如果值大于2就留下
分组
将数据将指定的规则进行分组
groupBy返回Map集合
val list = List(1, 2, 3, 4, 5, 6)
println(list.groupBy(_ % 2 == 0))
val list = List(1, 2, 3, 4, 5, 6)
val stringToInts = list.groupBy(data => {
if (data % 2 == 0) {
"偶数"
} else {
"奇数"
}
})
println(stringToInts)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WnUZQzp4-1689507716363)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230704101005111.png)]
mapValues
这个函数会将map的每一个value取出来再进行传进来的函数操作
val map = Map("a" -> 1, "b" -> 3, "c" -> 5)
println(map.mapValues(_ + 10))
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v2KmWgvi-1689507716363)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230704105720500.png)]
sortBy排序
默认从小到大排序 如果数据类型为String那么将字符转化为ASCII码进行比较
如果要从大到小可以使用reverse方法反转
val list = List(1, 7, 3, 6, 9, 6)
println(list.sortBy(data => {
data
}))
反转排序
val list = List(1, 7, 3, 6, 9, 6)
list.sortBy(data => data)(Ordering.Int.reverse)
object test {
def main(args: Array[String]): Unit = {
val user1 = new User(10, 20)
val user2 = new User(10, 30)
val user3 = new User(20, 20)
val list = List(user1, user2, user3)
//这里表示使用age进行排序如果相等就使用money进行降序
val list2 = list.sortBy(data => (data.age, data.money))(Ordering.Tuple2(Ordering.Int, Ordering.Int.reverse))
}
case class User(age: Int, money: Int)
}
sortWith排序
这个方法需要传入一个函数用来实现排序逻辑
val list = List(1, 7, 3, 6, 9, 6, 8)
//x表示左边数据y表示右边数据
println(list.sortWith((x, y) => x > y))
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c6JLfXyv-1689507716363)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230704142705767.png)]
object test {
def main(args: Array[String]): Unit = {
val user1 = new User(10, 20)
val user2 = new User(10, 30)
val user3 = new User(20, 20)
val list = List(user1, user2, user3)
val users = list.sortWith((x, y) => {
if (x.age > y.age) {
true
} else if (x.age == y.age) {
x.money > y.money
} else {
false
}
})
println(users)
}
case class User(age: Int, money: Int)
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xkwi8XKy-1689507716363)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230704143128082.png)]
WorldCont
val source: BufferedSource = Source.fromFile("file/hello")
//获取每一行
val strings: List[String] = source.getLines().toList
strings
.flatMap(_.split(" "))//将数据使用" "分割
.map((_, 1))//将数据变为2元组
.groupBy(_._1)//将数据进行分组 返回Map集合
.mapValues(_.size)//将value的长度替换原来的List
.toList//将Map转换为List[(String,Int)]
.sortBy(_._2)(Ordering.Int.reverse)//将个数进行排序 降序
.take(3)//获取前3个
聚合函数
reduce
下列案例实现了将list中的所有元素进行相乘
底层使用reduceLeft实现如果要从右边开始可以使用reduceRight
val list = List(1, 2, 3, 4, 5, 2, 3, 5)
println(list.reduce((x, y) => x * y))
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fkxLtiIy-1689507716364)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230704155721762.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3TRupscv-1689507716364)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230704162101624.png)]
fold
这个函数需要传入2个参数第一个为初始值得值第二个为实现逻辑
底层为foldLeft实现
val list = List(1, 2, 3, 4, 5, 2, 3, 5)
println(list.fold(100)(_ - _))
scan扫描
这个方法可以将reduce或者fold的计算过程和结果放进List集合中返回
val list = List(1, 2, 3, 4, 5, 2, 3, 5)
println(list.scan(5)(_ - _))
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p47Wohp7-1689507716364)(C:\Users\li’zheng’jie\AppData\Roaming\Typora\typora-user-images\image-20230704163611842.png)]
Queue
队列里面的数据先进先出
val que = new mutable.Queue[String]()
//添加数据
que.enqueue("a", "b", "c", "d")
que += "e"
//获取一个元素
println(que.dequeue())
并行集合
使用par可以把集合变为并行集合
//Thread.currentThread().getName表示获取线程的名称
val result1 = (1 to 5).map { x => Thread.currentThread().getName }
//加上par表示将这个集合变为并行集合
val result2 = (1 to 5).par.map { x => Thread.currentThread().getName }
println(result1)
println(result2)
模式匹配
基本语法
在scala中使用match进行匹配
如果都不满足那么执行case _
注意:在case中不能像java的switch一样使用表达式
在match中是有顺序匹配的如果将case _ 放在第一个判断的话那么使用匹配都将执行csae _ 的内容
在match中如果没有匹配那么就会报错抛出scala.MatchError
val age = 10
age match {
case 10 => {
println(s"年龄$age")
}
case 20 =>{
println(s"年龄$age")
}
case _ =>{
println("年龄为其他")
}
}
匹配类型
def describe(x: Any) {
x match {
case i: Int => println("Int")
case s: String => println("String")
case m: List[Int] => println("List")
case c: Array[Int] => println("Array[Int]")
case _ => println("其他")
}
}
describe(List[String]()) //List
匹配数组
for (arr <- Array(
Array(0), //0
Array(1, 0), //1,0
Array(0, 1, 0), //0*
Array(1, 1, 0), //没有匹配的Array
Array(1, 1, 0, 1), //没有匹配的Array
Array("hello", 90) //hello,90
)) {
arr match {
case Array(0) => println("0")
case Array(x, y) => println(x + "," + y)
case Array(0,_*) => println("0*")
case _ => println("没有匹配的Array")
}
}
匹配列表
for (arr <- Array(
List(0), //0
List(1, 0), //1,0
List(0, 0, 0), //0*
List(1, 0, 0), //没有匹配的List
List(88), //没有匹配的List
)) {
arr match {
case List(0) => println("0")
case List(x, y) => println(x + "," + y)
case List(0,_*) => println("0*")
case _ => println("没有匹配的List")
}
}
val list = List(1, 2, 3, 4, 5) //1-2-List(3, 4, 5)
val list2 = List(1, 2)//1-2-List()
val list3 = List(1)//没有匹配
list3 match {
case f :: s :: r => println(f + "-" + s + "-" + r)
case _ => println("没有匹配")
}
匹配元组
for (arr <- Array(
(0, 1),//0...
(1, 0),//1-0
(1, 1),//1-1
(1, 0, 2)//没有匹配
)) {
arr match {
case (0, _) => println("0...")
case (y, 0) => println("" + y + "-0")
case (a, b) => println("" + a + "-" + b)
case _ => println("没有匹配")
}
}
val map = Map(
(("河北", "鞋"), 2),
(("河北", "衣服"), 4),
(("河南", "衣服"), 3),
(("河南", "电脑"), 4)
)
map.toList.map {
case ((prv, item), cnt) => {
(prv, (item, cnt))
}
}
对象匹配
object test {
def main(args: Array[String]): Unit = {
val user = User("张三",25)
user match {
case User("张三", 25) => println("这是需要的用户张三")
case _ => println("这不是我们需要的用户")
}
}
case class User(name:String,age:Int)
}
偏函数
偏函数指定是不完全的函数PartialFunction
下列代码实现了将除了Int类型的值去除的功能
val list = List(1, 2, 3, "4", 5)
val list2 = list.collect { case i: Int => i + 1 }
异常
将可能发生异常的操作放在try中如果发生异常就处理catch的逻辑并在处理完成后处理finally的逻辑
如果没有发生异常就正常执行程序
在java中不能将Exception放在ArithmeticException异常的前面匹配因为Exception的异常比ArithmeticException的异常范围大包括ArithmeticException异常所以报错
但是在scala中不会报错scala中顺序执行如果匹配就执行
try {
val i = 0
val j = 10 / i
} catch {
case e: ArithmeticException=>{
println("ArithmeticException")
}
case e: Exception => {
println("Exception")
}
}finally {
println("结束")
}
隐式转换
编译器在编译的时候如果出现了错误,此时可以自动查找相应的转换操作,如果查找到就会进行2次转换
使用implicit关键字
object test {
def main(args: Array[String]): Unit = {
implicit def transfer(d: Double): Int = {
d.toInt
}
val i:Int = ttt()
println(i)//10
println(i.isInstanceOf[Int])//true
}
def ttt(): Double = {
10.5
}
}
object test {
def main(args: Array[String]): Unit = {
implicit def useri(user: User): User2 = {
new User2
}
val user = new User
user.d()
user.a()
}
class User2 {
def a(): Unit = {
println("小红aaaaaaa")
}
}
class User {
def d(): Unit = {
println("小明User")
}
}
}
case class User(implicit password: String = "000000"){println(password)}
implicit val ppp = "111111"
new User //111111
如果类的前面增加implicit关键字表示当前类应用于隐式转换
object test {
def main(args: Array[String]): Unit = {
val user = new User
user.d()
user.a()
}
implicit class User2(user:User) {
def a(): Unit = {
println("小红aaaaaaa")
}
}
class User {
def d(): Unit = {
println("小明User")
}
}
}
泛型
协变
object test {
def main(args: Array[String]): Unit = {
val message1:Message[User] = new Message[User]()
val message2:Message[User] = new Message[Parent]()//报错
val message3:Message[User] = new Message[Child]()
}
class Message[+T]{
}
class Parent{
}
class User extends Parent{
}
class Child extends User{
}
}
逆变
object test {
def main(args: Array[String]): Unit = {
val message1:Message[User] = new Message[User]()
val message2:Message[User] = new Message[Parent]()
val message3:Message[User] = new Message[Child]()//报错
}
class Message[-T]{
}
class Parent{
}
class User extends Parent{
}
class Child extends User{
}
}
正则表达式
正则表达式作用于匹配字符串是否符合规则
//定义规则
val regex = "zh".r//判断字符串中是否有zh
//定义数据
val str = "zhangsan"
//使用规则校验数据
val maybeString: Option[String] = regex.findFirstIn(str)
val iterator: Regex.MatchIterator = regex.findAllIn(str)
if (maybeString.isEmpty) {
println("字符串不符合规则")
} else {
println("字符串符合规则:" + maybeString.get)
}
//定义规则
val regex = "^\\d{11}$".r//^表示头$表示尾|表示或者
val regex2 = "[0-9]{11}".r
//定义数据
val str = "12312312311"
//使用规则校验数据
val maybeString: Option[String] = regex.findFirstIn(str)
val iterator: Regex.MatchIterator = regex.findAllIn(str)
if (maybeString.isEmpty) {
println("字符串不符合规则")
} else {
println("字符串符合规则:" + maybeString.get)
}