Scala语言学习
计算函数
函数式编程相关
面向对象
集合类型
计算函数
1、转换类函数
val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8) //过滤 val re: List[Int] = list.filter(_ % 2 == 0) //map val re2: List[Int] = list.map(_ * 2) //扁平化 val list1: List[List[Int]] = List(List(1), List(11, 12), List(21, 22, 23), List(31, 42, 43, 44)) val flatten: List[Int] = list1.flatten //扁平映射(结合map与flatten) val re3: List[Int] = list1.flatMap(list => { list :+ 999 //对数据中的元素添加一个数字再扁平化 }) //分组 val re5: Map[Int, List[List[Int]]] = list1.groupBy(_.size) val re6: Map[Int, List[Int]] = list.groupBy(_ % 2)
2、规约类函数
val re7: Int = list.reduce(_ + _) //reduce聚合操作 val re8: Int = list.fold(100)(_ + _) //类似reduce,第一个参数给定初始值 val map1: Map[String, Int] = Map("a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4) val map2: Map[String, Int] = Map("a" -> 10, "b" -> 20, "cc" -> 30, "dd" -> 40) val map: Map[String, Int] = map1 ++ map2 println(map == map1) val stringList: List[String] = List("wgy", "wgy 123", "wgy 465 798", "wll wgy", "wll 123") val list2: List[String] = stringList.flatMap(_.split(" ")) val map3: Map[String, List[String]] = list2.groupBy(w => w) val map4: Map[String, Int] = map3.map(kv => (kv._1, kv._2.size)) val tuples: List[(String, Int)] = map4.toList.sortWith((a, b) => a._2 > b._2).take(3) println(tuples)
3、并行执行
val strings: immutable.IndexedSeq[String] = (1 to 5).map(x => Thread.currentThread().getName) val strings1: ParSeq[String] = (1 to 5).par.map(x => Thread.currentThread().getName) println(strings1)
3、模式匹配
val x: Int = 5 val y: Int = x match { case 0 => println("798") 798 case 1 => println("458") 458 case _ => println("111") 111 } //模式守卫(可以对范围做匹配,我没明白if else不好使吗) val z: Int = x match { case i if i > 0 => println("798") 798 case i if i == 0 => println("458") 458 case _ => println("111") 111 } //匹配常量 def match1(x: Any): Unit = x match { case 1 => println("Int 1") case "wgy" => println("String wgy") case true => println("boolean true") case '+' => println("") } //匹配类型 def match2(x: Any): Unit = x match { case i: Int => println("798") case s: String => println("458666") case list: List[String] => println("458777") //注意List的泛型匹配时存在泛型擦除,导致泛型被忽略所有List的类型都会匹配 case list: Array[String] => println("458888") //注意Array不存在泛型擦除 case a => println("111") } //匹配数组、列表(List)、元祖同理(自上而下匹配,当匹配到后边将不再匹配) for (elem <- List(Array(1, 0, 1), Array(1, 1), Array(0, 1), Array(0))) { elem match { case Array(0, _) => println("(0,_)") //必须有两个元素,且第一个元素为0 case Array(0, _*) => println("(0,...)") //匹配开头0,后边有多个或者没有元素的数组类型 case Array(1, 1) => println("(1,1)") case Array(x, y) => println("(x,y)") case Array(x, 0, z) => println("(x,0,z)") case _ => println("_") } } //元组 val (xx, yy) = (1, "wgy") //相当于x=1,y="wgy" val List(first, second, _*) = List(2, "wll", 465, 798) //first=2,second=wll val fir :: sec :: rest = List(1, 2, 3, 4, 5) //区别上边fir=1 ,sec=2 ,rest=List(3,4,5) val list: List[(String, Int)] = List(("a", 1), ("b", 2), ("c", 3), ("d", 4), ("e", 1666)) for ((v1, v2) <- list) println(v1 + ":" + v2) for (("a", v) <- list) println(v) //相当于过滤了第一个元素为”a“的
函数式编程相关
1、匿名函数
def main(args: Array[String]): Unit = { //定义一个匿名函数 val myFun: String => Unit = (name: String) => { println(name) } //定义一个函数 def func(thisFun: String => Unit): Unit = { thisFun("wgy scala") } //调用 func(myFun) /** 省略1 * 1、定义的匿名函数入参类型可以省略 * 2、当只有一个入参时,入参的括号以省略 * 3、匿名函数只有一行,大括号可以省略 */ func(name => println(name)) /** 省略2 * 1、当参数只出现一次,入参可以省略后边参数用_代替 * 2、能推断出是一个函数题的话可以直接省略(_)如:func(println) */ func(println(_)) //========================举例: def f2(thisFun: (String, String) => String): String = { thisFun("1", "2"); } println(f2(_ ++ _)) //函数作为值返回 def f(a: Int): Int = { a + 123 } val f1: Int => Int = f val f3 = f _ }
2、闭包柯里化
def f1(num1:Int):Int=>Unit={ def f2(num2:Int):Unit={ println(num1+num2) } f2 _ } val intToUnit: Int => Unit = f1(456) intToUnit(678) intToUnit(1) intToUnit(2) f1(456)(789)
3、递归函数
//递归函数
def factorial(n: Int): Int = {
if (n <= 1) 1
else n * factorial(n - 1)
}/*
为优化栈溢出问题,使用尾递归
即自身的最后一行函数直接返回调用自身,不做其他操作
*/
def factorialTailrec(n: BigInt, acc: BigInt): BigInt = {
if (n <= 1) acc
else factorialTailrec(n - 1, acc * n)
}6、控制抽象(传值参数、传名参数)
def fun0(a:Int)={
println(a)
println(a)
}def fun1(a: =>Int)={
println(a)
println(a)
}def fun2():Int = {
println("函数调用")
23
}fun0(fun2())
println("=============")
fun1(fun2())
4、使用柯里化实现while
def myWhile(isdo: =>Boolean)(op: =>Unit):Unit={
if(isdo){
op
myWhile(isdo)(op)
}}var num=10
myWhile(num>0){
println(num)
num -= 1
•}懒加载
val sum= (a:Int,b:Int) =>{
println("开始结算")
a+b
}//懒加载
lazy val num = sum(1, 2)
println("开始输出结果")
println("输出结果1"+num)
println("输出结果2"+num)
面向对象
1、包对象(package Object)
一个包下可以生成一个,只有当前包下的类可以使用,子包也不可用
package object scalaStudy {
def commMethod(): Unit ={
println("wgy 学习sacls")
}var mess:String="13213213"
•}类
class Student {
@BeanProperty
var name: String = _
@BeanProperty
var age:Int=_
•}封装
•构造器
class Student() {//主构造器
@BeanProperty
var name: String = _
@BeanProperty
var age:Int=_
def this(name:String){//辅助构造器
this()
this.name=name
}}//使用var指定为带参数的主构造器
class Student2(var name :String, var age:Int)
//重写方法是需要增加override
class Student3() extends Student {//主构造器
override def mothed()={
println("这rr 是一个方法")
•}}封装与多态
2、抽象类
在子类中要重写抽象类中非抽象的属性时,其修饰必须使用val,否咋运行时报错
abstract class Per {
val name:String=""
}class Str extends Per {
override val name:String=""
•}伴生对象
//伴生类,类似单例模式,为去除static后静态方法使用
object Per{
//该函数调用是可以不写apply直接使用类名即可
def apply(name :String,age:Int):Per={
new Per(name,age)
}//使用实例
def main(args: Array[String]): Unit = {
val wgy: Per = Per("wgy", 18)
}}class Per private (name :String,age:Int) {
println("调用了私有的主构造器")
•}特质
1.当父类与特质中的属性重复时,需要明确重写
集合类型
三大集合:序列Seq、集Set、映射Map
对于集合类,scala提供了可并与不可变的版本
不可变集合:scala.collection.immutable
可变集合:scala.collection.mutable
1、数组
不可变数组(不可变指的长度不可变,其位置上的值是可以赋值的)
//创建不可变数组
val array1: Array[Int] = new Array[Int](5)
//使用伴生对象创建对象
val array2: Array[Int] = Array(4, 5, 6, 7)
//数组赋值
array2(2) = 1000
//访问数组
println(array2.apply(2))
//遍历数组
for (i <- array2.indices) println(array2(i)) //根据下标循环
for (elem <- array2) println(elem) //增强for循环
array2.foreach(println)
val iterator: Iterator[Int] = array2.iterator //遍历器循环
while (iterator.hasNext)
println(iterator.next())
//连接素连接转为String输出
println(array2.mkString("--"))
//添加元素(创建新的数组返回)
array2.:+(789) //往末尾追加数据
array2 :+ 789 //功能同上,放大调用时可以将.用空格代替或者省略;参数只有一个时可以将括号省略
array2.+:(456) //往数组前追加数据
456 +: array2 //功能同上,当方法名称以:结尾时,此时方法左边为参数右边为对象(:在对象测)
//创建多维数组
val array3: Array[Array[Int]] = Array.ofDim(2, 2)
可变数组
val buffer: ArrayBuffer[Int] = new ArrayBuffer
val buffer2: ArrayBuffer[Int] = ArrayBuffer(12, 45, 78, 1998)
//访问元素
println(buffer2(0))
//添加元素
buffer2 :+ 999
999 +: buffer2 //以上两种方法不会在本数组添加,需要在返回的新数组中操作
buffer2 += 999 //在数组前追加元素,返回原数组(操作符不推荐在可变数组中使用)
888 +=: buffer2 //由于scala只会对结尾为:的方法处理为参数在前对象在后,所以要想在数组前追加元素,需要加:
buffer2.append(1, 2, 3, 4) //在数组前追加(推荐使用方法调用)
buffer2.prepend(9, 8, 7, 6) //在数组后添加
buffer2.insert(1, 1998) //在指定位置添加元素
buffer2.insertAll(1, buffer) //在指定位置添加数组
//删除元素
buffer2.remove(buffer2.size - 1) //在指定下标后删除一个元素
buffer2.remove(buffer2.size - 1, 1) //在指定下标后删除n个元素
buffer2 -= 1998//按值删除,删除首次出现的第一个该元素
//可变数组互转为不可变数组
val array: Array[Int] = buffer2.toArray
val buffer3: mutable.Buffer[Int] = array.toBuffer
2、List列表
不可变列表(不可变指的内容,长度均不可变)
//创建列表
val list1: List[Int] = List(1, 2, 3, 4, 5) //使用伴生对象的apply生成对象
val list2: List[Int] = Nil.::(789) //使用Nil的::方法生成对象
val list3: List[Int] = 789 :: Nil //由于::方法以:结尾,固可以省略后使用参数在前对象在后方是调用
val list4: List[Int] = 789 :: 456 :: 123 :: 147 :: Nil //结合多个从后向前创建得到
//添加元素(与数组类似)
val listNew: List[Int] = 465 +: list1 :+ 798
//合并列表
val list5: List[Any] = list3 :: list4//不会合并两list,是将list3作为元素添加到list4头
val list6: List[Any] = list3 ::: list4//合并两List
val list7: List[Any] = list3 ++ list4//功能同上,合并两List
可变列表
//创建可变列表
val list1: Any = new ListBuffer[Int]()
val list2: ListBuffer[Int] = ListBuffer(123, 456, 798)
val list3: ListBuffer[Int] = ListBuffer(777, 888, 999)
//合并可变List
val list4: ListBuffer[Int] = list2 ++ list3 //将两个List合并后返回新的list
list2 ++= list3 //将list3追加到list2队尾,并返回list2
list3 ++=: list2//追加到list2队首
//操作队列
list2.append(555)
list2.remove(1,2)
list2.update(1,10)
list2-=15//根据值删除元素
3、Set集合
不可变Set
//创建不可变Set
val set1: Set[Int] = Set(1, 2, 3, 4, 4, 5, 6, 7)
//添加元素
val set2: Set[Int] = set1.+(789)
val set3: Set[Int] = set1 + 456
//合并set
val set4: Set[Int] = set2 ++ set3
//删除元素
val set5: Set[Int] = set4 - 789
可变Set
//创建可变Set
val set1: mutable.Set[Int] = mutable.Set(1, 2, 3, 4, 4, 5, 7)
//添加元素
val set2: mutable.Set[Int] = set1 + 100 //原set不变,返回新的set
set1 += 555 //在set1中添加元素
set1.add(666) //同上
//删除元素
set1 -= 555
set1.remove(666)
//合并set
val set3: mutable.Set[Int] = set1 ++ set2
4、Map集合
不可变Map
//创建不可变Map
val map1: Map[String, Int] = Map("wgy" -> 10, "wll" -> 20, "whh" -> 18)
//访问元素
val maybeInt: Option[Int] = map1.get("wgy")
val value: Int = maybeInt.get//调用get方法获取对应值(None.get报错,Some.get返回值)
val value2: Int = map1.getOrElse("wgy",18)//直接获取值
val value3: Int = map1("www")//当值不存在报错
map1.keys.foreach(println)//遍历
可变Map
//创建可变Map
val map1: mutable.Map[String, Int] = mutable.Map("wgy" -> 10, "wll" -> 20, "whh" -> 18)
//添加元素
map1.put("wnb",100)
map1+=(("wnb",200))
map1.update("wnb", 300)
val map2: mutable.Map[String, Int] = map1.updated("wnb", 666)//区别update,该方法返回新对象
map2.remove("wgy")
//合并map
map1++=map2
5、元组
val tuple: (Int, String, Char, Boolean) = (1, "1", 'a', true)
tuple.productIterator.foreach(println)
6、可变队列
val queue: mutable.Queue[Int] = new mutable.Queue[Int]()
queue.enqueue(1,2,3,4,5,6,111)
val va: Int = queue.dequeue()
浙公网安备 33010602011771号