Scala学习笔记
1、变量var,常量:val
在Scala中可以不指定数据类型,数据类型可以自行推断
如果要声明 数据类型: 变量名 冒号 如:类型 a:Int
和java语法一样
变量定义的规则:可以遵循java的规则(字母下划线打头,数字不能打头)
//定义变量
// var name="蒋欢"
// var gao=1.71 //身高
// val tiz:Int=50 //体重
// print(s"姓名为${name}身高${gao}体重${tiz}")
}
// 数据类型的指定声明和 低高精度运算的规则:
// 1: java中 数据类型可以分为两大类型: 基本、引用
// 基本:
// 字节型: byte (1字节) 整型: short(2) int(4) long(8) 浮点型: Float(4) Double(8) 布尔型 :boolean(1)
//2、低精度会自动转换为高精度 short byte char 在运算时会自动转换为 int类型
2、控制语句
// var a=4
// if (a==5){
// print("a==5")
// }
// else{
// print("a不等于5")
// }
循环控制语句
continue与 break 语句
continue世界树本次循环,在进入下一次循环
break是结束整个循环
// 循环控制语句
// to 包括 左右两个数 <= end untile :不包括右边数 <end
//打印出 0 - 9 的数字
// for (i <- 0 to 9){
// print(i)
// }
// 循环控制语句
// 循环守卫:就是我们for里面加的条件
//输出 0-10 中的偶数
// for (i<- 0 to 15 ;if i %2==0;if i<=10){
// print(i)
// }
// 二重循环
// for(i <- 1 to 2){
// for (j <- 1 to 2){
// print(i*j)
// }
// }
// ↓ 可以吧两个for写在一起
for(i <- 1 to 2; j <- 1 to 2)
{
print(i*j)
}
// var a= 10;
// do {
// print(a);
// a-=1;
// }while(a!= 0)
//在循环中引用其他变量
//也可以在他前面加条件(循环守卫)
for(i <- 1 to 10;if i % 2 ==0;j=i*5){
print(j)
}
// yield 将我们指定的变量的值 装入一个数组Vector中
//也可以将yield 自定义 比如 j*j
val jh = for(i<- 1 to 2;j=i*i) yield j
println(jh)
3、方法和函数
定义
函数:为完成某一功能的程序语句的集合
方法:类中的函数称为方法
格式:def 函数名(参数名1:参数类型1,参数名2:参数类型2.。。。。。):返回类型={函数体}
区别
1、Scala语言可以在任何的语法结构中申明任何的语法
2、函数没有重载和重写
3、Scala中函数可以嵌套定义
// 方法和 函数
// def sumint(a:Int,b:Int):Int={
// return a+b;
// }
//print(sumint(1,2))
// 函数和方法: 函数可以使用 def和 val定义 但是 方法只能使用def定义
// 函数必须要有 参数列表,方法可以没有 参数列表
// 这是函数↓
//val addint = (a:Int,b:Int)=>a+b
// print( Scala1.addint(1,2))
//方法转换为 函数: 方法名后面跟一个:空格 下划线 告知编译器 '我们是要将方法转换为函数' 而不是去调用这个方法!
// val f1=_m;
// def m(a:Int,b:Int):Int =a*b
// val newm=m _
// print(newm)
//
//1、无参数,无返回值 调用这种情况的时候 可以只写 函数名不用打括号
//调用的时候也不能加
def f1(){
println("没有返回值")
}
//2、无参,有返回值
def f2():String={
val sm=10+20
"abc" //函数如果有返回值,但是没有指定return语句的情况下,默认将函数中最有一行作为返回值
}
//3、有参数,无返回值
def f3(food:String):Unit={
println("我吃的是:"+food)
//return "面包" 函数在定义无返回值的情况下,加上return 不起作用
}
//4、有参数,有返回值
def f4(food:String):String={
return food
}
//5、多参数,无返回值
def f5(food:String,weight:Double,price:Double):Unit={
println("早餐是:"+food+"重量是+"weight+"价格是:"+price)
}
//6、多参数,有返回值
def f6(foot:String,nums:Int,price:Double):String={
println("早餐吃了:"+nums+"个"+food+"花费了"+price)
return "吃好了"
}
//7、有默认参数值的函数
//调用时:不写默认得参数,他会自动默认,如果要修改其一,
/就要去指定参数名称,比如:gender=**,age=**
def f7(name:String,gender:String="男",age:Int=20):String={
println(name+" "+gender+" "+age)
return "Student Info"
}
//8、不定参数得函数 * 号
//一个函数既有固定参数,也有不定参数,不定参数通常在固定参数后
def f8(name:String,scores:Int*):Unit={
println(name+"成绩为:"+scores)
}
//调用
f8("李",90,111,20,321)
//9、递归函数 一个函数存在调用自身的情况
//阶乘
def f9(n:Int):Int={
if (n==0){
return 1
}else{
return n*f9(n-1)
}
}
10、惰性函数
函数的返回值声明为
lazy
时候,返回值被取用的时候,函数才执行,否则不执行
def f11():String={
println("惰性函数执行")
return "ok"
}
//调用
lazy val result = f11() //不输出 因为没使用
print(result+....") //输出 ,因为使用了
函数至简原则:
4、匿名函数:
//匿名函数
(a:Int,b:Int) => {
a+b
}
//匿名函数作为形参 将我们用爱调用的参数列表替换为 匿名函数的参数列表 -不要参数名 也就是匿名
def Test(func:(Int,Int)=>Int): Unit = {
print(func(1,2))
}
def main(args: Array[String]): Unit = {
Test((a,b)=>a+b)
}
至简原则
5、异常
注解:
数据类型共通方法
mkString
.mkString()方法的使用:
mkString(seq:String)方法是将原字符串使用特定的字符串seq分割。
mkString(statrt:String,seq:String,end:String)方法是将原字符串使用特定的字符串seq分割的>同时,在原字符串之前添加字符串start,在其后添加字符串end。
size
返回长度
6、数组(Array,ArrayBuffer)
高级操作
scala map,flatmap,filter的用法:scala map,flatmap,filter的用法
定长数组
// 定长 :关键字 Array[数组类型](数组的长度)
// 打印出的是 数组的 hashcode 值也就是地址
// >>hashCode值(散列值):——将对象映射为一个整型值,不同的对象返回不同的数值
// hash值来源于这个对象的内部地址转换成的整型值。
// val a=new Array[Int](8)
// print(a) //输出:[I@ea4a92b hascode值
变长数组(数组缓冲)
如果要使用变长数组,则要导入
import scala.collection.mutable.ArrayBuffer
声明
// 如果要使用变长数组,则要导入 import scala.collection.mutable.ArrayBuffer
// 变长定义:ArrayBuffer[类型]()
import scala.collection.mutable.ArrayBuffer
val b=ArrayBuffer[Int](5) // 或者new ArrayBuffer [int],一个空的数组缓冲,
准备存放整数,这是空数组
val b2=ArrarBuffer(1,2,3,4) // 初始化数据
特殊方法
//增加元素(尾部)
b+=1 // ArrayBuffer (1),用+=在尾端添加元素
// print(b)
b+=(2,3,4) //在末尾 添加多个 : +=
// print(b) //ArrayBuffer(1, 2, 3, 4)
//append(elem:Int*)
b.append(8) //1,2,3,4,8
b.append(9,10) //1,2,3,4,8,9,10
b ++= Array(5,6,7) //在末尾添加 一个数组 :++=
// print(b) //ArrayBuffer(1, 2, 3, 4, 5, 6, 7)
b++= ArrayBuffer(8,9) // 在末尾添加一个数组缓冲
// print(b) //ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
//指定位置追加: insert(index:Int,elems:类型*) index 索引 elems:插入的数据(可以是多个)
b.insert(0,-1,0)
val c=ArrayBuffer[Int]()
c+=0 //c=ArrayBuffer(0)
c.insert(1,1,2,3,4) // 在指定位置插入元素,insert格式:(下标,元素,元素,元素)
//print(c) // ArrayBuffer(0,1,2,3,4)
//删除元素 -=
c-=4 //ArrayBuffer(0,1,2,3)
//remove
c.remove(0) //remove 在指定索引处 删除元素 remove(索引位:Int)
println(c) //ArrayBuffer(1,2,3)
//remove(索引位,删除个数)
remove(2,3) //从索引为2开始 删除3个
//数组遍历
val arr1=Array(1,2,3
//下标法
for(i<-0 until arr1.length){
println(arr1(i))
}
//增强的for循环
for (elem<-arr1){
println(elem)
}
//foreach
arr1.foreach(print)
}
val a
7、元组(Tuple)
元组:可以存放相同和不相同数据类型的数据结构
定义
//元组的定义,最多可以存放22个元素
val t1=(3,1,'hello',12,33,44)
读取
数组名._ 索引 ,注意索引位从1开始
//数组名._ 索引 注意索引位从1开始
println(t1._1)
遍历
productIterator 方法
for(elem<-t1.productIterator){
println(elem)
}
8、集合(Set)
Set集合中的元素不可重复
TreeSet:里面的元素自动按字典排序(abc,123.。。)
HashSet:里面的元素是无序的
不可变集合的定义
导入的包为:immutable
val set1=scala.collection.immutable.HashSet(5,4,6,"jh","ww","jh")
val set2=scala.collection.immutable.TreeSet(5,4,6)
println(set1)
println(set2)
可变集合的定义
导入的包为:mutable 可以导入包 也可以不写 写在定义的时候 如下:
val set3=scala.collection.mutable.HashSet(10,30,20)
set3.add(40)
println(set3) //Set(30, 20, 10, 40)
set3.remove(10)
println(set3) //Set(30, 20, 40)
set集合元素的读取
println("head取第一个元素:"+set3.head)
//读取第一位元素以外的所有元素
println("tail取除了第一个元素以外的:"+set3.tail)
//读取特定数量的元素 take 从第一个开始 取 指定数量个元素
println(set3.take(2))
//head取第一个元素:30
//tail取除了第一个元素以外的:Set(20, 40)
//Set(30, 20)
set集合的遍历
//1
for(elem<-set3){
println(elem)
}
//2
set3.foreach(println)
可变集合的特殊操作
//add:添加元素
//remove:删除元素
set3.remove(30)
set3.add(35)
println(set3)
集合的长度
println(set3.size)
Set共通的高级操作
//判断Set集合是否包含某个元素: contains 返回布尔值
val set4=Set("jh","jh1","jh2")
println(set4.contains("jh"))
//判断集合是否为空 返回值为布尔
println(set4.isEmpty)
val set5=Set() //定义一个空集合
println(set5.isEmpty) //True
//有关集合与数学相关的操作
//最大值、最小值、集合元素之和
val set6=Set(5,3,2,1,4)
println("集合最大值:"+set6.max)
println("集合最小值:"+set6.min)
println("集合元素之和:"+set6.sum)
println("集合元素之和:"+set6.reduce((a,b)=>a+b))
println("集合元素之和:"+set6.reduce( _+_ )) //至简原则
//合集 ++
val set7=Set(5,3,2,1,4)
val set8=Set(5,3,6,7)
val set9=set7 ++ set8
println("合集(++)为:"+set9)
//差集
println("set7和set8的差集:"+(set7--set8))
println("set8和set7的差集:"+(set8--set7))
//set7和set8的差集:Set(1, 2, 4)
//set8和set7的差集:Set(6, 7)
//交集 共同的元素
println("set8和set7的交集:"+(set7.intersect(set8)))
//Map,filter,flatMap
//groupBy:分组
val gbSet=set9.groupBy(elem=>elem%2 ==0)
println(gbSet)
//Map(false -> Set(5, 1, 7, 3), true -> Set(6, 2, 4))
map:对集合中的元素进行转换
val set1=Set("hello","jh","jh","word")
val mapset=set1.map(elem=> (elem,1))
println(mapset)
flatMap:
9、列表(List)
定义
元素可以重复,都是不可变的
空列表
val list=List() //空列表
val list2=Nil //也是空列表
val list3=List(1,2,3)
val list6=List("1","2")
for (elem<-list3){
println(elem)
}
连接操作
:: (整体连接)
元素和列表,列表和列表
//连接 :: 整体
val list4=list3::list2
println(list4) //List(List(1, 2, 3))
List.concat()
列表中元素的连接 List.concat(多个列表 )
//列表中元素的连接 List.concat(多个列表 )
val list5=List.concat(list3,list6)
println(list5) //List(1, 2, 3, 1, 2)
List.contains
判断一个元素是否再list中
元素取值
head
取第一个元素
tail
取 除了第一个元素
take
前 n个元素
last
取最后一个元素
size
长度
val list8=List(1,2,3);
println(list8.head)
println(list8.tail)
println(list8.take(3))
println(list8.last)
输出
1
List(2, 3)
List(1, 2, 3)
3
转换
toArray 转换数组
toSet 转换集合
排序
sorted
去重
println(list8.distinct)
map flatmap groupBy reduce filter
//map 数据转换
val set2=Set("a","b")
println(set2.map( (elem)=>{elem.toUpperCase} ))
val list1=List("java python","scala hello")
val list2=List(List("java","scala"),List("java","scala"))
val list3=List(Array("java","scala"),Array("java","scala"))
val list4=List(Set("java","scala"),Set("java","scala"))
println(list1.flatMap( elem=>elem.split(" ") ))
println(list2.flatMap(elem=>elem))
println(list3.flatMap(elem=>elem))
println(list4.flatMap(elem=>elem))
//flatMap 先map再flat扁平化
val list1 = List("java python", "scala hello")
val list2 = List(List("java", "scala"), List("java", "scala"))
val list3 = List(Array("java", "scala"), Array("java", "scala"))
val list4 = List(Set("java", "scala"), Set("java", "python"))
println(list1.flatMap(elem => elem.split(" ")))
println(list2.flatMap(elem => elem))
println(list3.flatMap(elem => elem))
println(list4.flatMap(elem => elem))
val list6 = list4.groupBy(elem => elem.contains("python"))
println("分组:" + list6)
list6.foreach(println)
}
val list9=List(5,3,1,4,7,9)
val result= list9.groupBy(e =>e%2==0) //分组奇偶数
println(result) //Map(false -> List(5, 3, 1, 7, 9), true -> List(4))
键值对(Map)
不可变
key具有唯一性(基于Set)
val map1=Map("a"->1,"b"->2)
println(map1)
可变
导入包 import scala.collection.mutable.Map
//可变
import scala.collection.mutable.Map
val map2=Map("c"->3,"d"->4)
println(map2)
取值
//取值
println(map2.get("c")) //Some(3)
println(map2.get("c").get) //3
println(map2.get("1313")) //None
// println(map2.get("1313").get) //报错
//为了预防key不存在,可以使用getOrElse
// def getOrElse[B1 >: B](key : A, default : => B1) : B1 = { /* compiled code */ }
//key不存在时 可以指定输出的默认值
println(map2.getOrElse("dadadaa",100))
遍历
//遍历
//keys,keySet 两者一样
for (key <- map2.keySet){
println(key+":"+map2.get(key).get)
}
//foreach
map2.foreach(println)