Scala

1.scala环境搭建

网址:https://www.scala-lang.org/

  • 安装步骤

    • Scala需要使用JVM来运行字节码文件,所以需要确保安装了jdk1.8

    • 下载对应的scala安装文件scala-2.12.15.msi

    • 解压安装包到C:\Program Files (x86)

    • 配置scala环境变量

  • 安装完成后与JAVA_HOME类似的为Scala配置SCALA_HOME,并将%SCALA_HOME%\bin添加到Path

  • 在cmd尝试运行scala,安装正确会进入如下界面

Scala

Scala

Scala

2.scala特性:

  • 面向对象特性:每个值都是对象

  • 函数式编程

  • 静态类型

  • 扩展性

  • 并发性

3.scala和java的关系

Scala与Java和众多JVM语言的共通之处在于,使用专门的编译器(Compiler)将源代码编译成字节码(Bytecode)文件,并最终使用JVM(Java Virtual Machine)执行程序,所以具有和Java相同的优良移植性。

Scala

4.第一个scala程序

4.1为IDEA下载Scala插件

Scala

4.2 创建空的maven工程

Scala

Scala

4.3创建Scala源代码目录

Scala

4.4 标记为源码目录

Scala

4.5添加ScalaSDK全局库

Scala

4.6创建HelloWorld单例对象

Scala

4.7 编写HelloWrold

 1 /*
 2 object:关键字,声明一个单例对象
 3 
 4 */
 5 object Test {
 6   /*
 7   main方法:从外部可以直接调用执行的方法
 8   def 方法名称(参数名称 : 参数类型):返回值类型 = {方法体}
 9   */
10   def main(args: Array[String]): Unit = {
11     print("helloWord")
12     println(3)
13   //var\val 变量名 : 数据类型 [= 变量值]
14     var aa=3;
15     val bb="qqqq"
16    var f:Int=3
17     println(aa)
18     println(bb)
19   }
20 }

5.基本语法

  • 区分大小写

  • 类名 - 对于所有的类名的第一个字母要大写。 如果需要使用几个单词来构成一个类的名称,每个单词的第一个字母要大写。

  • 方法名称 - 所有的方法名称的第一个字母用小写。

注释:

①单行注释//

②多行注释/* */

③文档注释/** */

变量和常量

①基本语法

var 变量名 [:变量类型] = 初始值 var i:Int =10

val 常量名 [:常量类型] = 初始值 val j:Int =20

能使用常量的地方不用变量

  • 声明变量时,类型可以省略,编译器自动推导

1 var a1=10
2 val b1=20
  • 类型确定后,就不能修改,说明scala是强数据类型语言

1 var a2=12 //a2为int类型
2 a2="hello" //报错
  • 变量声明时,必须有初始值

  • 在声明定义一个变量时,可以使用var或val修饰,var修饰的变量可改变,val修饰的变量不可改

字符串拼接

  • 字符串,通过+号连接

1 val name: String = "aa"
2 val age: Int = 18;
3 println(age + "岁的" + name + "在学习")
4 //*用于将一个字符串重复多次并拼接
5     println(name*3)//aaaaaa
  • printf用法:字符串,通过%传值

printf("%d岁的%s在学习",age,name)
  • 字符串模板(插值字符串):通过$获取变量值

1 println(s"${age}岁的${name}在学习")
  • 格式化模板字符串

1 //the num is 2.33
2 println(f"the num is ${num}%2.2f")
  • 三引号表示字符串,保持多行字符串原格式输出

 1 /*
 2   select *
 3     from
 4      Test
 5      where
 6      name=aa
 7      and
 8      age>18
 9 */
10 val sql =
11     s"""
12        |select *
13        |from
14        | Test
15        | where
16        | name=${name}
17        | and
18        | age>${age}
19        |""".stripMargin
20     println(sql)

键盘输入

  • 输入信息

 1 import scala.io.StdIn
 2 
 3 object Test1 {
 4   def main(args: Array[String]): Unit = {
 5     //输入信息
 6     println("请输入你的姓名")
 7     val name:String=StdIn.readLine()
 8     println("请输入你的年龄")
 9     val age:Int=StdIn.readInt()
10     //从控制台打印输出
11     println(s"${age}岁的${name}")
12   }
13 }
  • 从文件中读取数据

1 import scala.io.Source
2 
3 object Test2 {
4   def main(args: Array[String]): Unit = {
5     //从文件中读取数据
6     Source.fromFile("path").foreach(print)
7   }
8 }
  • 将数据写入文件

1 val writer=new PrintWriter(new File("path"))
2     writer.write("hello")
3     writer.close()

6.数据类型

Scala

  • 与Java类似的Scala有Byte、Short、Int、Long、Float、Double、Char、Boolean,8种常用值类型。

  • 与Java不同的是,Scala中 真·万物皆对象,所以没有所谓包装类,上面这八个值类型就是对象。

①整数类型

1 //1.整数类型
2 val a1:Byte=127
3 val a2:Byte=-128
4 
5 val a3=12//整数默认类型为Int
6 val a4=1823737493939L//长整型数值定义
7 
8 val b1:Byte=10
9 val b2:Byte=(b1+20).toByte//强制类型转换

②浮点类型

1 val f1:Float=1.23f
2 val d1:Double=23.333

③字符类型

1 val c1:Char='a'//a
2 val c2:Char='9'//9

④控制字符

1 val c3:Char='\t'//制表符
2 val c4:Char='\n'//换行符

⑤转义字符

1 val c5='\\'//表示\自身
2 val c6='\“'//表示”

⑥布尔类型

布尔型字面量有 true 和 false

⑦空类型

  • Nothing和Null

  • Nothing是所有类型的子类型,也称为底部类型。没有一个值是Nothing类型的。它的用途之一是给出非正常终止的信号,如抛出异常、程序退出或者一个无限循环(可以理解为它是一个不对值进行定义的表达式的类型,或者是一个不能正常返回的方法)。

  • Null是所有引用类型的子类型(即AnyRef的任意子类型)。它有一个单例值由关键字null所定义。Null主要是使得Scala满足和其他JVM语言的互操作性,但是几乎不应该在Scala代码中使用。我们将在后面的章节中介绍null的替代方案。

 1 object Test3 {
 2   def main(args: Array[String]): Unit = {
 3     //1.空值Unit
 4     def m1():Unit={
 5       println("m1被调用")//m1被调用
 6     }
 7     val a=m1()
 8     println(a)//()
 9       
10    //2.空引用Null
11         var student:Student=new Student("alice",23)
12     student=null
13     println(student)//null
14           
15   //3.Nothing
16    def m2(n:Int):Int={
17       if(n==0)
18       throw new NullPointerException//抛出异常
19       else
20         return n
21     }
22     val b=m2(2)
23     println(b)//2
24   }
25 }

自动类型转换

  • 值类型可以按照下面的方向进行转换:

Scala

  • 自动提升原则:有多种类型的数据混合运算时,系统优先自动将所有数据转换成精度大的数据类型,然后再进行计算

1 val a1:Byte=10;
2     val b1:Long=122333333L
3     val result:Long=a1+b1
4  val result1:Int=(a1+b1).toInt//强制转换
  • 把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之会进行自动类型转换

1         val a2:Byte=10
2     val b2:Int=a2
3     //val c2:Byte=b2//报错
  • (byte、short)和char之间不能进行类型转换

1     val a3:Byte=10
2     val c3:Char='b'
3     val c4:Byte=c3
4     println(c4)//运行报错
  • byte、short、char三者可以计算时,要先转换成int类型

1 val a4:Byte=10;
2     val b4:Short=12
3     val c5:Char='c'
4     //val result2:Short=a4+b4//报错
5     val result2:Int=a4+b4
6     println(result2)//22

强制类型转换

  • 将数据从高精度转换为低精度,就需要进行强制类型转换,但数据会丢失精度

1 val n1:Int=2.5.toInt
2 println(n1)//2
3 val n1:Int=-2.9.toInt
4 println(n1)//-2
  • 强转符号只针对最近的操作符有效,往往会使用小括号提升优先级

1     val n2:Int=(2.6+3.7).toInt
2     println(n2)//6

数值类型和String类型的转换

  • 数值转String

1 val n3:Int=27
2     val s:String=n3+" "
3     println(s)
  • String转数值

1 val m:Int="12".toInt
2     println(m)

继承层次

  • 与Java不同的是Scala的类型转换通过asInstanceOf[目标类型]进行类型强转

 1 package com.bd2108.jwl.scala
 2 
 3 object scala08_继承层次 {
 4   def main(args: Array[String]): Unit = {
 5     def f1()={
 6       throw new NullPointerException
 7     }
 8     //scala中判断类型
 9 val bool = "aa".isInstanceOf[String]
10 
11     //scala中类型强转
12     val i = 11.asInstanceOf[Long]
13   }
14 }

7.运算符

  • +-*/%可以完成和 Java 中相同的工作,但是有一点区别,他们都是方法。你几乎可以用任何符号来为方法命名。

算术运算符+、-、*、/、%

 1 object Test {
 2     def main(args: Array[String]) {
 3        var a = 10;
 4        var b = 20;
 5        var c = 25;
 6        var d = 25;
 7 println("a + b = " + (a + b) );//30
 8 println("a - b = " + (a - b) );//-10
 9 println("a * b = " + (a * b) );//200
10 println("b / a = " + (b / a) );//2
11 println("b % a = " + (b % a) );//0
12 println("c % a = " + (c % a) );//5   
13     }
14 }

关系运算符==、!=、>、<、>=、<=

 1 object Test {
 2     def main(args: Array[String]) {
 3        var a = 10;
 4        var b = 20;
 5 println("a == b = " + (a == b) );//false
 6 println("a != b = " + (a != b) );//true
 7 println("a > b = " + (a > b) );//false
 8 println("a < b = " + (a < b) );//true
 9 println("b >= a = " + (b >= a) );//true
10 println("b <= a = " + (b <= a) );//false
11     }
12 }

逻辑运算符&&、||、!

 1 object Test {
 2     def main(args: Array[String]) {
 3        var a = true;
 4        var b = false;
 5 
 6 println("a && b = " + (a&&b) );//false
 7 println("a || b = " + (a||b) );//true
 8 println("!(a && b) = " + !(a && b) );//true
 9     }
10 }

位运算符~、&、|、^、<<、>>、>>>

 1 object Test {
 2     def main(args: Array[String]) {
 3 var a = 60;   /* 60 = 0011 1100 */  
 4 var b = 13;   /* 13 = 0000 1101 */
 5 var c = 0;
 6 
 7 c = a & b;    /* 12 = 0000 1100 */ 
 8        println("a & b = " + c );//12
 9 
10 c = a | b;    /* 61 = 0011 1101 */
11        println("a | b = " + c );//61
12 
13 c = a ^ b;    /* 49 = 0011 0001 */
14        println("a ^ b = " + c );//49
15 
16 c = ~a;       /* -61 = 1100 0011 */
17        println("~a = " + c );//-61
18 
19 c = a << 2;   /* 240 = 1111 0000 */
20      println("a << 2 = " + c );//240
21 
22 c = a >> 2;   /* 15 = 1111 */
23      println("a >> 2  = " + c );//15
24 
25 c = a >>> 2;   /* 15 = 0000 1111 */
26      println("a >>> 2 = " + c );//15
27     }
28 } 

赋值运算符=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=

 1 object Test {
 2     def main(args: Array[String]) {
 3        var a = 10;       
 4        var b = 20;
 5        var c = 0;
 6 
 7        c = a + b;
 8   println("c = a + b  = " + c );//30
 9 
10        c += a ;
11   println("c += a  = " + c );//40
12 
13        c -= a ;
14        println("c -= a = " + c );//30
15 
16        c *= a ;
17       println("c *= a = " + c );//300
18 
19        a = 10;
20        c = 15;
21        c /= a ;
22        println("c /= a  = " + c );//1
23 
24        a = 10;
25        c = 15;
26        c %= a ;
27        println("c %= a  = " + c );//5
28 
29        c <<= 2 ;
30      println("c <<= 2  = " + c );//20
31 
32        c >>= 2 ;
33      println("c >>= 2  = " + c );//5
34 
35        c >>= a ;
36      println("c >>= a  = " + c );//0
37 
38        c &= a ;
39      println("c &= 2  = " + c );//0
40       
41        c ^= a ;
42      println("c ^= a  = " + c );//10
43 
44        c |= a ;
45      println("c |= a  = " + c );//10
46     }
47 } 

运算符重载

  • 中缀表达式

  • scala中可以将对象.方法(参数)简写成对象 方法 参数

 1 package com.bd2108.jwl.scala
 2 
 3 object scala09_运算符重载 {
 4   def main(args: Array[String]): Unit = {
 5     ==|==>()
 6     def ==|==>():Unit={
 7      // println("11111")
 8     }
 9 
10     //scala中万物皆对象
11     1+1
12     //本质上也是对象调用方法:对象.方法名(参数)
13     1.+(1)
14     //scala中允许使用中缀表达式简化以上操作
15     //简化前:对象.方法名(参数)
16     //简化后:对象  方法名  参数
17     val str = "a,b,c".split(",")
18     val ss="a,b,c" split ","
19 
20     //中缀表达式的变形
21     //对象.方法
22     //对象  方法
23     val trim = "   qqq  ".trim//返回无空格的字符串
24     println(trim)
25 }

8.流程控制

1.if-else表达式

  • Scala中提供与大部分编程语言中类似的if-else选择结构语句

  • 语法: if(expr) { expr为true时执行的语句 } else { expr为false时执行的语句 }

 1 package com.bd2108.jwl.scala
 2 
 3 object scala12_if_else {
 4   def main(args: Array[String]): Unit = {
 5     //缺省的else分支返回值的类型是空代码的类型Unit,在处理返回值类型时需要注意
 6     val a=10
 7     val b=12
 8    val c= if (a>b){
 9       a
10     }else{ }
11     println(c)
12 
13     if (a>b) a else b
14   }
15 }

2.while和do-while表达式

  • while和do-while表达式固定返回Unit

  • while语法: while(expr){ expr为true时反复执行的语句 }

1 var first = 0
2 var second = 1
3 var fibonacci = 0
4 while (fibonacci < 50) {
5   println(fibonacci)
6   first = second
7   second = fibonacci
8   fibonacci = first + second
9 }
  • do-while语法: do{ expr为true时反复执行的语句 } while (expr)
1 var i = 53672
2 var sum = 0
3 do {
4   sum += i % 10
5   i /= 10
6 } while (i > 0)
7 println(sum) // 23
  • 需要注意的是Scala中没有提供break和continue的关键字

  • 如果要实现类似的功能,可以使用控制循环条件、函数封装+return或BreaksAPI

1 var i=1
2     Breaks.breakable{
3       while (i<11){
4         println(i)
5         if (i==5) Breaks.break()
6         i+=1
7       }
8     }

3.for推导式

  • 语法:for (enumerators) { 循环体 }

    • 枚举器(enumerators):指的是一组以分号分割的枚举器,枚举器可以由一个产生新变量的生成器(generator)以及一个守卫(guard)组成。

1 //for中可以添加多个枚举器,类似java的嵌套循环
2    for (i <-1 to 9;j <-1 to i){
3 print(s"${j}*${i}=${i*j}\t")
4       if (i==j) println()
5     }
    • 生成器(generator):指的是一个形如变量名 <- 集合的表达式,生成器会在每次迭代时从<-右边的集合中取一个元素赋值给<-左边的变量。
1  //for(元素 <- 集合){
2     // }
3     val str = Array("a", "b", "c")
4     for (arr<-str){
5       println(arr)
6     }
    • 守卫(guard):指的是一个形如if expr的表达式,expr为true时执行循环体,为false时类似Java中的continue操作,跳过当此继续下一次循环。
1 //for中可以添加守卫
2     for(i <-1 to 10 if i%2==0){
3       println(i)
4     }
1 val inclusive = 1.to(100)
2     println(inclusive)//Range 1 to 100
  • scala的for推导式

 1 //Int.to(范围的重点,自增的步长)
 2     for (i<-2.to(100,2)){
 3       println(i)//打印100以内的偶数
 4     }
 5 
 6 //打印一个集合,将集合中后一位元素与前一位元素拼接,形成一个新的元素
 7   val arr=Array("a","b","c")
 8     for (i<-arr.indices){
 9       if (i+1<arr.length){
10 println(arr(i)=arr(i)+arr(i+1))
11       }
12     }
13     println(arr.toList)//集合List(ab, bc, c)
14     println(arr)//地址
15   }
  • yield收集:加在for推导式末尾,可以将满足条件的元素收集到新的集合并返回

1 //yield收集
2     val ints = Array(12, 34, 56, 231, 456, 789)
3     //声明集合用于存储结果res
4     //遍历原有集合
5     //判断满足添加,则加入res
6     //yield加在for推导式末尾,可以将满足条件的元素收集到新的集合并返回
7     val res=for (x<-ints if x %2!=0) yield x
8     println(util.Arrays.toString(res))

9.表达式

  • 表达式是可以计算的语句

  • scala表达式可以省略分号;

  • scala表达式的值可以不被变量接收

 1 package com.bd2108.jwl.scala
 2 
 3 object scala01_表达式 {
 4   def main(args: Array[String]): Unit = {
 5     //1.scala表达式中可以省略分号;
 6     3+2
 7     //2.scala表达式的值可以不被变量接收
 8     2
 9     "aqaa"
10   }
11 }
  • 值类型

    • 与java类似,有Byte、Short、Int、Long、Float、Double、Char、Boolean8中常用值类型

    • 与java不同的是scala中万物皆对象,所以没有包装类,值类型就是对象

10.代码块

  • 可以使用{ }将0行或若干行语句包裹起来形成一个整体,这个整体被称作代码块

  • 代码块的值是块中最后一行表达式的值

 1 package com.bd2108.jwl.scala
 2 
 3 object scala02_代码块 {
 4   def main(args: Array[String]): Unit = {
 5     //1.可以使用{}将0行或若干行语句包裹起来形成一个整体,这个整体被称作代码块
 6     //2.代码块的值是块中最后一行表达式的值
 7     val res={
 8       1
 9       2
10       3
11     }
12     println(res)//3
13   }
14 }

11.方法

  • 方法由def关键字定义,def后面跟着一个名字、参数列表、返回类型和方法体

  • 语法:def 方法名 (参数名:参数类型):返回值类型={方法体}

1 def add(x: Int, y: Int): Int ={
2   x + y
3 }
4 println(add(1, 2)) // 3
  • 与java类似,scala的方法就是将代码块加上 方法名 参数 返回值

  • scala返回值类型默认为Unit

1     //1.返回值
2     //1.1 scala返回值类型默认为Unit
3     def m1():Unit={ }
4     //也可以写成
5     def m2(){ }
  • 如果需要有返回值,就要在参数列表和方法体之间加上=,scala会自动根据方法体的最后一行语句推断返回值类型
1 //1.2 如果需要有返回值,就要在参数列表和方法体之间加上=
2     //scala会自动根据方法体的最后一行语句推断返回值类型
3     def m3(a:Int)={
4       a+1
5       "sss"
6     }
7     println(m3(2))//sss,代码块内最后一行语句是代码块的值
  • scala允许在方法声明时为参数添加默认值

  • scala方法调用时可以使用匿名参数的方式

 1 package com.bd2108.jwl.scala
 2 
 3 object scala03_方法 {
 4   def main(args: Array[String]): Unit = {
 5     //2.参数
 6     //2.1 scala允许在方法声明时为参数添加默认值
 7     def sum(a:Int=1,b:Int=2)={
 8       a+b
 9     }
10     sum(4,8)
11     sum(5)
12     sum()
13     println(sum())//3
14 
15     //2.2 scala方法调用时可以使用匿名参数的方式
16     sum(b=12,a=30)   
17 }
  • scala中也可以支持可变长度参数,与java类似 一个方法只能包含一个可变长度参数,可变长度参数必须放在参数列表末尾
1 //2.3 scala中也可以支持可变长度参数
2     //与java类似  一个方法只能包含一个可变长度参数,可变长度参数必须放在参数列表末尾
3     def sum1(x:Int*)={
4       println(x.sum)//15
5     }
6     sum1(1,2,3,4,5)
  • scala方法的参数列表为空时,可以省略()
1 //2.4 scala方法的参数列表为空时,可以省略()
2     f1()
3     //f1,省略()的写法也是正确的,但是不提倡这么用
4     f2
5   }
6   def f1()=123//方法,参数列表为空
7   val f2=456//常量

12.函数

  • 函数是带有参数的表达式

  • 语法:(参数名:参数类型)=>{函数体}

  • scala中main方法使用def声明,除了书写位置,其他语法和方法与java类似

  • method 方法,声明在类中(直接属于类的代码块),用于描述类的行为

  • function 函数,声明在任意位置(可以属于类,可以属于方法,可以属于其它函数)用于描述参数与 返回值之间的映射关系

  • scala中也提供了使用匿名函数的方式声明函数,(参数)=>{函数体}

    • 匿名函数f作为其他函数的参数时,参数类型可以省略不写

    • 如果是二元匿名函数,并且参数的声明顺序和使用顺序一致,并且都只用了一次,可以使用_代替

 1 package com.bd2108.jwl.scala
 2 
 3 object scala04_函数 {
 4   // java中的main方法: void main(String[] args) { }
 5   // scala中的main方法: main(args: Array[String]): Unit = { }
 6   //使用def声明的函数,除了书写位置,其他语法和方法与java类似
 7   def main(args: Array[String]): Unit = {
 8     
 9     //scala中也提供了使用匿名函数的方式声明函数
10     //(参数)=>{函数体}
11     val f1:Int=>Int=(b:Int)=>{
12       b+1
13     }
14 
15     //一元函数
16     val i:Int=2
17     val s:String="SSS"
18     val res=f1(2)
19     println(res)//3
20 
21     //实现加减乘除运算
22     val calc=(x:Int,y:Int,op:(Int,Int)=>Int)=>{
23       op(x,y)
24     }
25     def calc1(x:Int,y:Int,op:(Int,Int)=>Int):Int={
26       op(x,y)
27     }
28     val res1=calc1(1,2,(a:Int,b:Int)=>a+b)
29     println(res1)//3
30 
31     //匿名函数calc1作为其他函数的参数时,参数类型可以省略不写
32     val res2=calc1(1,2,(a,b)=>a+b)
33 
34     //如果是二元匿名函数,并且参数的声明顺序和使用顺序一致,并且都只用了一次,可以使用_代替
35     calc1(1,2,_ + _)
36     calc1(1,2,(x,y)=>x*x+y*y*y)
37 
38 
39     val array = new Array[String](3)
40     //foreach[U](f:String=>U)
41     array.foreach(x=>println(x))//null null null
42     
46   }
47 }
  • 我们可以定义一个匿名函数(即没有名字),来返回一个给定整数加一的结果。

(x: Int) => x + 1
  • 我们也可以将函数赋值给一个变量,相当于给匿名函数起一个名字。

  • 访问这个变量时,就是在调用这个函数。

  • 这时这个变量的类型就是一个函数,在函数式编程范式中,函数是一等公民,与Int、String等对象一样,可以作为一个变量的类型。

1 val addOne = (x: Int) => x + 1
2 println(addOne(1)) // 2
  • 函数可以带有多个参数

1 val add = (x: Int, y: Int) => x + y
2 println(add(1, 2)) // 3
  • 函数可以不带参数

1 val getTheNum = () => 23
2 println(getTheNum()) // 23

13.类

  • scala中类的声明语法

1 //class 类名{
2   //构造器
3   //成员属性
4   //成员方法
5 //}
  • scala中class的【主构造器】写在类的声明位置

  • 【主构造器】的参数列表中,如果使用var/val修饰的参数会直接作为类的成员属性

  • 成员变量如果是常量 必须设置初始值

  • 成员变量如果是变量 不需要设值初始值,可以使用_代替

  • @BeanProperty:自动根据权限生成符合java bean规范的访问接口,java代码通过get、set方法获得类的属性

  • 可以使用private将成员设值为类内私有访问,scala也支持为私有属性提供例外

  • scala由于只有一个主构造器,所以通过辅助构造器的语法 扩展构造器重载

  • 辅助构造器使用def声明,方法名为this,必须直接或间接调用主构造器

 1 package com.bd2108.jwl.scala
 2 import scala.beans.BeanProperty
 3 
 4 object scala05_类 {
 5   def main(args: Array[String]): Unit = {
 6     //class 类  object 对象
 7     //类 是一系列具有相同属性和方法的实体的抽象(模板)
 8     //对象 是使用new关键字和class构造器创建的一个类的实例
 9     val stu = new Student("1001")
10     stu.id="aaa"
11 
12     val t = new Teacher("admin",12,'1')
13     val t1 = new Teacher("aa",'2')
14     val t2 = new Teacher(11,'1')
15     val t3 = new Teacher("ss")
16   }
17 
18 }
19 
20 //scala中class的【主构造器】写在类的声明位置
21 //【主构造器】的参数列表中,如果使用var/val修饰的参数会直接作为类的成员属性
22 class Student(var id:String){
23   //成员变量如果是常量  必须设置初始值
24   @BeanProperty
25   //自动根据权限生成符合java bean规范的访问接口,java代码通过get、set方法获得类的属性
26   val name:String="admin"
27   //成员变量如果是变量 不需要设值初始值,可以使用_代替
28   @BeanProperty
29   var age:Int=_
30   //可以使用private将成员设值为类内私有访问
31   //scala也支持为私有属性提供例外
32   private var gender:Char='2'
33   //设值包级别的外部访问
34   private[bd2108] var weight:Int=_
35 
36   def eat()={
37   }
38   private def play()={
39   }
40 }
41 
42 //scala由于只有一个主构造器,所以通过辅助构造器的语法  扩展构造器重载
43 class Teacher(var name:String,var age:Int,val gender:Char){
44   //使用def声明 方法名为this
45   //辅助构造器  必须直接或间接调用主构造器
46   def this(name:String,gender:Char){
47     this(name,0,gender)
48   }
49   def this(age:Int,gender:Char){
50     this("0",age,gender)
51   }
52   def this(name:String){
53     this(name,0,'0')
54   }
55 }

java调用scala

 1 package com.bd2108.jwl.scala;
 2 
 3 public class Test {
 4     public static void main(String[] args) {
 5         Student stu=new Student("1001");
 6 System.out.println(stu.getName());
 7         stu.setAge(12);
 8  System.out.println(stu.getAge());
 9     }
10 }

14.对象

  • scala为了方便开发者声明单例对象,提供了object关键字,本质上scala会编译出一个匿名类作为模板,并未这个模板创建一个单例对象

 1 package com.bd2108.jwl.scala
 2 
 3 //如果一个class和一个object声明在同一个scala源代码文件中,class和object的名字完全一致
 4 //此时,我们将class称为object的伴生类,object称为class的伴生对象
 5 class Person {
 6   var name:String=_
 7   var age:Int=_
 8 }
 9 object Person{
10   //object中可以使用apply声明一些特殊方法
11   //当调用这些方法时,可以直接使用 对象名(参数)
12   def apply(name: String): Person = {
13     val p = new Person
14     p.name=name
15     p
16   }
17 
18   def apply(name: String, age: Int): Person = {
19     val p=new Person
20     p.name=name
21     p.age=age
22     p
23   }
24 
25   def eat():Unit={
26   }
27 }
  • 案例类,用case修饰

1 package com.bd2108.jwl.scala
2 
3 //case修饰的class称之为案例类
4 //案例类可以自动生成伴生对象和全参的apply用于类的实例化
5 case class Person1(var name:String,var age:Int)
  • 可以通过引用类的名字来访问一个对象

 1 package com.bd2108.jwl.scala
 2 
 3 object scala06_对象 {
 4   def main(args: Array[String]): Unit = {
 5     //希望可以直接通过"类名"调用
 6     //并且希望JVM中的全局变量唯一
 7     var name="aaa"
 8 
 9     //scala为了方便开发者声明单例对象,提供了object关键字
10     //本质上scala会编译出一个匿名类作为模板,并未这个模板创建一个单例对象
11     val p = Person("admin")
12     val p1 = Person("admin", 12)
13     val P2 = Person1("ROSE", 10)
14   }
15 }

15.特质

  • 特质是一个使用trait关键字声明的包含某些字段和方法的结构,类似于Java中的接口(interface)。特质允许多继承。

1 trait Person {
2   def eat(food: String): Unit
3 }
  • 特质也可以有默认的实现。

1 trait Person {
2   def eat(food: String): Unit = {
3     println("用碗吃" + food)
4   }
5 }
  • 可以使用extends关键字来继承特质,使用override关键字来覆盖默认的实现。

1 class NormalPerson extends Person
2 
3 class GanfanPerson extends Person {
4   override def eat(food: String): Unit = {
5     println("用盆吃" + food)
6   }
7 }
1 val normalPerson = new NormalPerson
2 normalPerson.eat("臊子面") // 用碗吃臊子面
3 val ganfanPerson = new GanfanPerson
4 ganfanPerson.eat("臊子面") // 用盆吃臊子面
  • scala为了提高程序的灵活性,允许在创建对象时,临时进行特质的混入

  • 混入本质上是创建了一个匿名子类,同时继承了当前类和混入的所有特质,并使用匿名子类创建实例

 1 package com.bd2108.jwl.scala
 2 
 3 object scala07_特质 {
 4   def main(args: Array[String]): Unit = {
 5     //类似于java代码中的interface接口
 6     //scala也提供了trait
 7     //scala为了提高程序的灵活性,允许在创建对象时,临时进行特质的混入
 8     //混入本质上是创建了一个匿名子类,同时继承了当前类和混入的所有特质,并使用匿名子类创建实例
 9     val student = new Student with Gamer with Coder
10     student.study()
11     student.play()
12     student.coding()
13     //接口的作用:为了解决类的多继承中,多个父类拥有相同的实现方法,导致子类调用时,会出现二义性问题
14     //接口中默认所有方法都声明成抽象方法,即使多个父接口中有相同的方法,调用时也需要重写并调用实现方法
15     //无法直接调用父接口中的抽象方法,不存在二义性
16     val x = new X
17     x.study()
18     x.play()
19     x.coding()
20   }
21 }
22 class  X extends Student with Gamer with Coder
23 //class Student extends Gamer with Coder{
24   class Student{
25     def study():Unit={
26       println("学习")
27     }
28   }
29   trait Gamer{
30     def play():Unit={
31       println("游戏")
32     }
33   }
34   trait Coder{
35     def coding():Unit={
36       println("编程")
37     }
38   }

16.隐式操作

  • apply和update方法

  • 定义在object中名为apply的一系列方法在调用时可以直接使用对象名(参数)的形式完成调用

  • Scala中不可变数组被定义为Array对象,更新数组中的元素时,可以使用update方法,或其隐式形式

  • 数组对象(索引)=值等价于 数组对象.update(索引,值)

 1 //数组:
 2     //java中写法:int[] arr=new Array[Int](3);
 3     //arr[0]=12;
 4     //int i=arr[0];
 5     val arr = new Array[Int](5)
 6 
 7     //scala虽然提供了完全面向对象的语法操作,但是为了简化或者适应其他语言规范,同步提供了一些【隐式操作】
 8     //数组的取值
 9     //val i = arr.apply(0)
10     val i = arr(0)
11     arr.update(0,22)
12     arr(0)=22
13   }

17.Option类型

  • Scala为单个值提供了对象的包装器,表示那种可能存在也可能不存在的值。

  • 他只有两个有效的子类对象,一个是Some,表示某个值,另外一个是None,表示为空,通过Option的使用,避免了使用null、空字符串等方式来表示缺少某个值的做法。

 1 package com.bd2108.jwl.scala
 2 
 3 import scala.collection.mutable
 4 
 5 object scala10_Option {
 6   def main(args: Array[String]): Unit = {
 7     //scala中设计了一个Option用来返回可能为空的返回值
 8     //Option有两个子类
 9     //None  当值为空时返回None实例
10     //Some  当有值时,将返回值封装在Some中并返回Some对象
11     val map = new mutable.HashMap[String, String]()
12    /* val key = map.get("k")
13     println(key.get)*/
14    val maybeString:Option[String] = map.get("k")
15     if (maybeString.isInstanceOf[Some[String]]){
16       println(maybeString.get)
17     }else{
18       println("值不存在")
19     }
20     val str:String = map.getOrElse("k1", "v1")
21     println(str)
22   }
23 }

18.异常

  • 与Java类似的,Scala提供异常处理机制用于终止错误的程序运行和错误提示。

  • 但是Scala没有“受检”异常,我们不需要声明说函数或者方法可能会抛出某种异常。受检异常在编译器被检查,Java必须声明方法所会抛出的异常类型

 1 package com.bd2108.jwl.scala
 2 import java.io.{File, FileInputStream}
 3 
 4 object scala11_异常 {
 5   def main(args: Array[String]): Unit = {
 6     //scala没有提供受检异常
 7     val file = new File("")
 8     var stream:FileInputStream =null
 9       try{
10      stream = new FileInputStream(file)
11     }catch {
12 case e:Exception=>println("读取失败")
13       }finally {
14         try {
15           stream.close()
16         }catch {
17           case e:Exception=>println("关闭资源失败")
18         }
19       }
20   }
21 }

19.数据结构与集合

1.数据结构

  • 数据结构讨论的是在抽象层面上一组具有一定关系的数据元素的存储处理

  1. 数据元素之间逻辑关系的分类,每种逻辑关系对应的操作。

  2. 每种逻辑关系在计算机内部的存储模式。

  3. 对应于每种存储模式和操作的实现过程。

2.逻辑结构

描述数据元素之间的逻辑关系

线性结构:一对一关系

  • 同一数据集合中的元素排成一个有序的序列。

  • 序列的第一个元素称起始结点(Initial Node),最后一个元素称终端结点(Terminal Node)

  • 任意一对相邻元素,前者是后者的直接前驱(Directly Predecessor),后者是前者的直接后继(Directly Successor)

  • 起始结点只有直接后继没有直接前驱,终端结点只有直接前驱没有直接后继。

  • 除起始节点和终端节点外,每个元素都只有一个直接前驱和一个直接后继。

树状结构:一对多关系

  • 同一集合中除了特殊的根(Root)元素之外,每个元素有且仅有一个直接前驱,后继数目不限。

  • 根元素没有直接前驱。

集合结构:松散的逻辑结构

  • 处于同一数据集合中的元素之间除同属于该集合这一联系外没有其他的关系。

  • 集合结构通常需要借助其他数据结构,比如线性结构和树。

  • 唯一专用于集合类型的数据结构是哈希表。

图状结构:多对多关系

  • 数据集合中每个元素的直接前驱和直接后继数目都不限。

3.存储结构

  • 顺序存储

  • 链接存储

  • 索引存储

  • 哈希存储

4.集合

  • scala中集合分为两大类1.可变长度集合 2.不可变长度集合

  • 另一方面,又分为三种类型:序列、集、映射

Scala

 

 

1.Seq 序列

  • Array封装了java中的[]

  • ArrayBuffer 可变长度数组,类似于java的ArrayList

  • String 封装了java的String char[]

  • Range 通常使用to、until用来生成连续的范围

  • List 基本链表

  • Queue 队列:先进先出

  • Stack 栈:先进后出

2.Set 集

  • HashSet

  • TreeSet

3.Map 映射

  • HashMap

  • TreeMap

4.Tuple 元祖

是一种可以保存不同类型元素的容器

语法:元祖:声明语法(元素1,元素2,...)

  • 元祖访问元素,使用 元祖.序号 例如t.1

  • 元祖最多存放22个元素

  • 包含两个元素的元组,称为二元组

 1 package com.bd2108.jwl.scala
 2 
 3 
 4 object scala19_元祖 {
 5   def main(args: Array[String]): Unit = {
 6     val a=3
 7     val b=2
 8     //写入一个函数 传入两个整数
 9     //返回a/b的商和余数 以及小数
10     def f1(a:Int,b:Int)={
11       //      val r = new Result
12       //      r.r1 = a / b
13       //      r.r2 = a % b
14       //      r.r3 = a.toDouble / b
15       val r1:Int=a/b
16       val r2:Int=a%b
17       val r3:Double=a.toDouble/b
18       (r1,r2,r3)
19     }
20     val res=f1(a,b)
21     //元祖访问元素,使用 元祖._序号  例如t._1
22     //元祖最多存放22个元素
23     val r1 = res._1
24     println(r1)
25 
26     //在上面的场景中,由于同时需要返回多个不同类型的对象
27     //如果使用集合  只能使用公共父类Any作为泛型
28     //如果使用对象 结构的变化不够灵活
29     //scala中提供了一种特殊的结构  元祖:声明语法(元素1,元素2,...)
30 
31 
32    //包含两个元素的元素称为二元组,或者叫pair  对偶
33     (1,2)
34     val tuple = (1, "2")
35     val tuple1 = 1 -> 2
36     println(tuple)
37     println(tuple1)
38   }
39 }

20.数组

  • 定长Array数组

 1 //1.Array
 2     //1.1创建
 3     val arr = new Array[Int](5)
 4     val arr1 = Array(1, 2, 3, 4, 5)
 5     //1.2查改
 6     //访问元素
 7     val i = arr(0)
 8     //修改元素
 9     arr1(0)=13
10     //1.3遍历
11         //方法1:
12     for (x<-arr1){
13       println(x)
14     }
15         //方法2:
16     for (i<-arr1.indices){
17       println(arr1(i))
18     }
19         //方法3:
20 arr1.foreach((x:Int)=>{println(x)})
21     arr1.foreach((x:Int)=>println(x))
22     arr1.foreach(x=>println(x))
23     arr1.foreach(println(_))
24     arr1.foreach(println _ )
25     arr1.foreach(println)
  • 变长数组ArrayBuffer

 1 //2.ArrayBuffer
 2     //2.1创建
 3     val buff = new ArrayBuffer[Int]()
 4     val buff1 = ArrayBuffer[Int]()
 5     //2.2增删改查
 6     //增
 7     buff.append(111,2222,333)
 8     //删
 9     buff.remove(2,1)
10     println(buff)
11     //改
12     buff(0)=11111
13     //查
14     val b=buff(0)
15     println(buff)
16 
17     //2.3遍历
18     buff.foreach(x=>println(x+1))
  • 多维数组 new int[3][3]

 1 //当在同一个类中存在两个相同的代码块时,代码下会出现灰色波浪线
 2     //解决方法:将相同部分提升成方法进行调用
 3     val array:Array[Array[Int]] = Array.ofDim[Int](3, 3)
 4     def print2DArray(arr: Array[Array[Int]]):Unit={
 5       array.foreach(arr=>{
 6         arr.foreach(a=>print(a+" "))
 7         println()
 8       })
 9     }
10     print2DArray(array)
11     /*array.foreach(x=>{
12       x.foreach(a=>print(a+" "))
13       println()
14     })*/
15     // 0 0 0
16     // 0 0 0
17     // 0 0 0
18 
19     //将二维数组第2行第三个元素改成8
20     array(1)(2)=8
21     print2DArray(array)
22     /*array.foreach(x=>{
23       x.foreach(a=>print(a+" "))
24       println()
25     })*/
26     //0 0 0
27     //0 0 8
28     //0 0 0
  • java与scala集合相互转换

 1 val list = Test1.getTestList
 2     val strings = new ArrayBuffer[String]()
 3     for (i <- 0 until list.size()){
 4       strings.append(list.get(i))
 5     }
 6     println(strings)//ArrayBuffer(111, 222, 333)
 7 
 8 
 9     //scala经常需要与JavaAPI互相调用
10     //为了使用方便,scala提供了与java之间集合类的转换器
11     //1.导入转换器
12     import scala.collection.JavaConverters._
13     //2.使用java集合.asScala可以返回scala集合
14     val res = list.asScala
15     print(res)//Buffer(111, 222, 333)
16     //3.使用scala集合.asJava可以返回java集合
17     res.asJava

21.import

  • scala中允许在任意位置使用import导入资源

  • 可以导入类、类的成员,允许为导入的成员设置别名

 1 package com.bd2108.jwl.scala
 2 
 3 import java.util
 4 
 5 object scala17_import {
 6   def main(args: Array[String]): Unit = {
 7     //scala中允许在任意位置使用import导入资源
 8     //1.除了导入类  允许导入类的成员
 9     import math._
10     sqrt(2)
11     //2.允许为导入的成员设值别名
12     import scala.collection.immutable.{HashMap=>HaHa}
13     import java.util.{HashMap=>HeiHei}
14     val map = new HaHa[String, String]
15     val map1 = new HeiHei[String, String]()
16     //3.导入时,将某些类匿名,或者时隐藏某个导入
17     import  java.lang.{String=>_}
18     new String
19   }
20 }

22.List

 1 package com.bd2108.jwl.scala
 2 
 3 object scala18_List {
 4   def main(args: Array[String]): Unit = {
 5     //List
 6     //1.创建
 7     val list = List(1, 2, 3, 4, 5)
 8     val list1 = List[Int]()
 9     //增删改查
10     //查看
11     val i = list(2)
12     print(i)
13     //在list的头部追加元素,产生新的list
14     println(list)
15    val list2= 8+:list
16     println(list2)//List(8, 1, 2, 3, 4, 5)
17     println(list)//List(1, 2, 3, 4, 5)
18       //在list的尾部追加元素,产生新的list
19     val list3=list2:+9
20     println(list3)//List(8, 1, 2, 3, 4, 5, 9)
21     //拼接两个list
22     val list4 = List(11, 22) ++ List(22, 33)
23     println(list4.distinct)//List(11, 22, 33)
24     //将多个元素按照顺序拼接到list的头部
25     //元素1::元素2::元素3::List()
26     val list5:List[Any] = 1 :: 2 :: List(2, 3) :: 4 :: List()
27     println(list5)//List(1, 2, List(2, 3), 4)
28 
29   }
30 }

23.Map

 1 package com.bd2108.jwl.scala
 2 
 3 import scala.collection.mutable
 4 
 5 
 6 object scala20_Map {
 7   def main(args: Array[String]): Unit = {
 8     //1.创建
 9     val map = mutable.HashMap[String, String]()
10     //直接使用map特质的apply方法,将元素在初始化时添加到map中
11     Map(("k1","v1"),("k2","v2"))
12     Map("k1"->"v1","k2"->"v2")
13     //增删改查
14     map.put("k1","v1")
15     map.put("k2","v2")
16     map.put("k1","v111")
17     map.put("k3","v3")
18     println(map)//Map(k2 -> v2, k1 -> v111, k3 -> v3)
19 
20     //去除所有key
21     val key = map.keySet
22     //去除所有value
23     val values = map.values
24 
25     //map取值
26     //1.Option[V] =  map.get(key)
27     val maybeString = map.get("k3")
28     //2.可以设值如果key不存在时的默认返回值
29     map.getOrElse("k5","v5")
30     //如果你非常确定这个key的存在,则可以使用map(key)取值
31     val v3 = map("k3")
32     println(v3)
33 
34 
35     //习题:统计一下字符串字母出现的次数
36     val str="jdowdfjskalaooqwwjmdkaskka"
37     val resmap = new mutable.HashMap[Char, Int]()
38     for (x<-str){
39      /* if (resmap.contains(x)){
40         // 如果结果集中 之前存在当前字符,则取出之前的数量 +1 写回去
41         val some = resmap.get(x)
42         var count = some.get
43         count += 1
44         resmap.put(x,count)
45       }else{
46         //如果不存在 1
47         resmap.put(x,1)
48       }*/
49       resmap.put(x,resmap.getOrElse(x,0)+1)
50     }
51     println(resmap)
52     //遍历
53     //使用for
54     for (t<-map){
55       val k = t._1
56       val v = t._2
57     }
58     //先获取所有key,然后再遍历keyset取出值value
59     for(k<-map.keySet){
60       val v = map(k)
61     }
62     //使用二元组遍历
63     for ((k,v)<-map){
64 
65     }
66     val list:List[(String,String)] = map.toList
67     println(list)
68   }
69 }

24.集合算子

  1 package com.bd2108.jwl.scala
  2 
  3 object scala21_集合算子 {
  4   def main(args: Array[String]): Unit = {
  5     val list = List(12, 1, 78, 33, 10, 897, 344)
  6     val list1 = List[Int]()
  7     //1.head last headOption lastOption
  8     val head = list.head//拿到第一个元素
  9     val last = list.last//拿到最后一个元素
 10     val headOption = list.headOption
 11     val lastOption = list.lastOption
 12    /* println(head)//12
 13     println(last)//344
 14     println(headOption)//Some(12)
 15     println(lastOption)//Some(344)*/
 16     val option = list1.headOption
 17     /*println(option)//None*/
 18 
 19 
 20     //2.tail init
 21     //tail  去掉第一个元素,保留剩下的元素
 22     //init  去掉最后一个元素,保留剩下的元素
 23     //val list = List(12, 1, 78, 33, 10, 897, 344)
 24     val tail = list.tail
 25     val init = list.init
 26     println(tail)//List(1, 78, 33, 10, 897, 344)
 27     println(init)//List(12, 1, 78, 33, 10, 897)
 28 
 29 
 30 
 31     //3.排序
 32     //升序排序 sorted
 33     val sorted = list.sorted
 34     //降序排序
 35     val reverse = list.sorted.reverse
 36     //降序排序并去掉一个最小值
 37     val init1 = list.sorted.reverse.init
 38     println(init1)//List(897, 344, 78, 33, 12, 10)
 39 
 40 
 41     //4.获取集合长度 size length
 42     val size = list.size
 43     val length = list1.length
 44     //判断集合是否为空 isEmpty  nonEmpty
 45     val empty = list.isEmpty
 46     val empty1 = list1.nonEmpty
 47     //println(empty)//false
 48    // println(empty1)//false
 49 
 50     //5.最值和算数
 51     //sum product(乘积) max min
 52     val product = List(1, 2, 3).product
 53     //println(product)
 54     val sum = List(1, 2, 3).sum
 55     val max = List(1, 2, 3).max
 56     //println(sum)
 57     //println(max)
 58 
 59 
 60     //6.count  forall  exists
 61     //6.1 按照条件对元素计数
 62     val list2 = List("ajdjdf", "ADHDJ", "sahdw2333")
 63     //计算a和A出现的次数(当str只用了一次时,可以省略用_代替
 64     //val i = list2.count(str=>str.toLowerCase.contains('a'))
 65     val i = list2.count(_.toLowerCase.contains('a'))
 66     //println(i)
 67     //6.2 用于判断集合中的元素是否全部满足某个条件
 68     //当所有元素都满足条件返回为true
 69     val bool = list2.forall(str => str.length > 10)
 70     //println(bool)
 71     val list3 = List(2, 3, 4, 5, 0, -10, 2, 4, -7)
 72     val bool1 = list3.forall(x => x >= 0)
 73     //println(bool1)
 74 
 75     //6.3 用于判断满足条件的元素在集合中是否存在
 76     //集合中只要有一个元素满足条件就返回为true
 77     val bool2 = list3.exists(_ < 0)
 78     //println(bool2)
 79 
 80     //7.过滤
 81     val list4 = for (x <- list3 if x > 0) yield x
 82     //println(list4)
 83     val list5 = list3.filter(x => x > 0)
 84     //println(list5)
 85     val list6 = list3.filterNot(x => x > 0)
 86    // println(list6)
 87 
 88     //分区  将满足要求的元素放在一个list集合,不满足的放在另一个list
 89     val p = list3.partition(_ > 0)
 90     println(p)
 91 
 92     //8.take 从集合中拿取元素个数,按照个数从左往右
 93     val list7 = list3.take(2)
 94     //println(list7)
 95     //takeRight  从右向左取值
 96     val list8 = list3.takeRight(3)
 97     //println(list8)
 98     //takeWhile 从左向右取值,一旦遇到不满足条件的元素,就停止取值,后面的元素不在遍历
 99     val list9 = list3.takeWhile(x => x > 0)
100    // println(list9)
101 
102 
103     //9.drop 丢弃
104     val list10 = List(122, 333, 12, -2, -78, 44)
105     //丢弃集合中最小的三个数
106     val list11 = list10.sorted.drop(3)
107     //println(list11)
108     //方式2:将集合升序排列,从右向左取出集合长度-3个数
109     list10.sorted.takeRight(list10.length-3)
110 
111     //dropRight  从右向左丢值
112     //dropWhile  从左向右丢值,一旦遇到不满足条件的元素,就停止丢弃
113 
114 
115     //10.span  将满足条件的放在一个集合,一旦遇到一个不满足条件的不管后面的元素是否还满足条件,都放在不满足条件的集合中
116     val tuple = list10.span(_ > 0)
117     println(tuple)//(List(122, 333, 12),List(-2, -78, 44))
118 
119     //11.splitAt
120     val tuple1 = list10.splitAt(2)
121     println(tuple1)//(List(122, 333),List(12, -2, -78, 44))
122   }
123 }

集合算子高级

 1 package com.bd2108.jwl.scala
 2 
 3 object scala22_集合算子高级 {
 4   def main(args: Array[String]): Unit = {
 5     val list: List[Int] = (1 to 10).toList
 6     //1.map 映射
 7     //1.1声明
 8     //def map[B](f: A => B): 集合[B] =
 9     //1.2参数
10     //参数f是一个一元函数  f的参数是源集合的元素类型
11     //f的返回值可以是任意类型
12     //1.3 返回值
13     //返回值类型与源集合类型相同,泛型是f的返回值类型
14     //1.4 作用
15     //map接收一个一元函数f,将源集合中的所有元素依次传入f,并将f的返回值收集到新的集合
16 
17     //将集合中的值全部+1
18     val map = Map("k1" -> 3, "k2" -> 5)
19     map.map(t => (t._1, t._2 + 1))
20 
21     val list1 = list.map(_ + "1")
22     println(list1)
23 
24     // 将集合中所有3的倍数自增1
25     //   所有2的倍数变成原来的2倍
26     //   并将所有结果放入新的集合
27     //   如果既不是3的倍数 也不是2的倍数则不保留
28     val list2 = List(1, 2, 3, 4, 5, 6, 7)
29     list2.filter(x => x % 3 == 0 || x % 2 == 0)
30       .map(x => {
31         if (x % 3 == 0) x + 1
32         else x * 2
33       })
34 
35 
36     //2.foreach
37     //2.1声明
38     //def foreach[U](f: A => U) : Unit = {
39     //2.2 参数
40     //参数f是一个一元函数  f的参数是源集合的元素类型
41     //f的返回值可以是任意类型
42     //2.3 返回值
43     //Unit
44     //2.4 作用
45     //与map类似接收一个一元函数f,将源集合中的元素依次传入f中
46     //不同的是,foreach不返回处理结果 而固定返回Unit
47     //通常用于将集合中的元素遍历输出到控制台或者外部存储
48     //             f: Int => Int
49     //               Int  => Unit
50     list2.foreach((x: Int) => println(x))
51     //                Any => Unit
52     list2.foreach(println)
53   }
54 }
  1 package com.bd2108.jwl.scala
  2 
  3 import scala.collection.mutable
  4 import scala.io.Source
  5 
  6 object scala23_集合算子高级 {
  7   def main(args: Array[String]): Unit = {
  8     val path="C:\\Users\\Administrator\\IdeaProjects\\bigDate1\\scala\\src\\main\\resources\\Harry.txt"
  9     //读取文本文件
 10     val source = Source.fromFile(path)
 11     val lines:List[String] = source.getLines().toList
 12     source.close()
 13     //统计文件中所有单词出现的数量
 14     val count = new mutable.HashMap[String, Int]()
 15     for (line<-lines){
 16       val words = line.split("\\s+")
 17       for (word<-words){
 18         val w = word.toLowerCase
 19           .replaceAll("\\W+","")
 20         count.put(w,count.getOrElseUpdate(w,0)+1)
 21       }
 22     }
 23     //println(count)
 24 
 25 
 26     // 1. flatMap  扁平化映射
 27     // 1.1 声明
 28     //    def flatMap[B,That](f: A => 集合[B]): That = {
 29     // 3.2 参数
 30     //    f是一个一元函数
 31     //    f的参数是源集合的元素类型,f的返回值是一个集合,并且集合的泛型可以是任意类型
 32     // 3.3 返回值
 33     //   返回值类型时源集合类型,泛型是f的返回值泛型
 34     // 3.4 作用
 35     //   当使用map算子时返回的结果为二维集合
 36     //   而实际需求希望拿到一维集合(将所有的内层集合的元素装到统一的容器中)
 37     //   则可以将map替换成flatMap
 38     //   flatMap在对集合进行映射的同时  将二维集合扁平化为一维集合
 39 
 40     //  lines:List[String]   =>  words:List[String]
 41     //    map(String => Array[String]) List[Array[String]]
 42     val list:List[Array[String]] = lines.map(line => line.split("\\s+"))
 43     //def flatMap[B,That](f:String=>Array[String]):List[String]={}
 44     val count1=new mutable.HashMap[String,Int]()
 45     val list1 = lines.flatMap(line => line.split("\\s+"))
 46     list1.foreach(word=>{
 47       val w = word.toLowerCase.replaceAll("\\W+", "")
 48       count1.put(w,count1.getOrElse(w,0)+1)
 49     })
 50 
 51 
 52     val str = List("shdj", "ssjffvn", "rfjfnvf", "jfnfcuds")
 53     val map = new mutable.HashMap[Char, Int]()
 54     //def flatMap[B,That](f:String=>Array[Char]):List[Char]={}
 55     val chars:List[Char] = str.flatMap(x => x.toCharArray)
 56     println(chars)
 57 
 58 
 59     //2.collect 收集
 60     //2.1 声明
 61     //def collect(pf: PartialFunction[A, B]): That = {
 62     // 2.2. 参数
 63     // 2.3. 返回值
 64     // 2.4. 作用
 65     //配合偏函数  进行输入和输出数量不对等的操作  输出 < 输入
 66     val list2 = List(1, 2, 3, 4, 5, 6, 7)
 67     list2.filter(x=>x%3==0 ||x%2==0).map(x=>{
 68       if(x%3==0)x+1
 69       else x*2
 70     })
 71 
 72    val pf= new PartialFunction[Int,Int] {
 73       /**
 74        * 判断传入的对象是否是需要处理的对象
 75        * @param x  输入的对象
 76        * @return   是否需要处理
 77        */
 78       override def isDefinedAt(x: Int): Boolean = {
 79         x%3==0 ||x%2==0
 80       }
 81 
 82       /**
 83        * 偏函数处理的具体逻辑
 84        * @param v1  满足条件的输入对象
 85        * @return    处理的结果
 86        */
 87       override def apply(v1: Int): Int = {
 88         if (v1%3==0) v1+1
 89         else v1*2
 90       }
 91     }
 92     val list3 = list2.collect(pf)
 93     val list4=list2.collect{
 94       // case 变量名 if 条件 => 返回值
 95       case x if x%3==0=>x+1
 96       case x if x%2==0=>x*2
 97     }
 98     println(list4)
 99   }
100 }

 

上一篇:JSP会员制图书管理系统idea开发mysql数据库web结构计算机java编程


下一篇:MyBatis中使用collection一对多分页查询时记录数量不准确的问题