240508Scala笔记

240508Scala笔记

Scala概述:

SCala是Java的拓展,在Java的基础上又拓展了一些语法,例如: 输出Hello World

复制代码
    println("HelloWorld")
    System.out.println("Hello Scala from Java")

上面两段代码都可以输出内容.

复制代码
package chapter01
​
/*
    object: 关键字,声明一个单例对象
*/
object HelloWorld {
    
/*
    main 方法: 从外部可以直接调用执行的方法
    def 方法名称(参数名称:参数类型):返回值类型 = {方法体}
*/
  def main(args: Array[String]): Unit = {
    println("HelloWorld")
    System.out.println("Hello Scala from Java")
  }
}

其中上面的object是一个单例对象.

object : 关键字,声明一个单例对象

main 方法:从外部可以直接调用执行的方法

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

Scala入门:

(下面是一段java代码)创建一个学生类:(对方法的引用)

Java代码:

复制代码
import scala.io.StdIn;
​
public class Student {
    private String name;
    private  Integer age;
    private  static  String school= "YelloRiwer";
​
    public Student(String name,Integer age){
        this.name = name;
        this.age = age;
    }
​
    public void printInfo(){
        System.out.println(this.name+" "+this.age+" "+ Student.school);
    }
​
    public static void  main(String[] args){
        Student alice = new Student("alice",20);
        Student bob = new Student("bob",23);
        alice.printInfo();
        bob.printInfo();
    }
}

运行结果:

复制代码
alice 20 YelloRiwer
bob 23 YelloRiwer

如果我想要静态且不想要他的属性那就需要Scala. 下面这段Scala代码和上面的Java代码一样,但是比Java代码简洁了许多:

Scala代码:

复制代码
package chapter01
​
class Student(name : String,age:Int) {
      def printInfo():Unit = {
        println(name+" "+age+" "+Student.school)
      }
}
//引入伴生对象
object Student{
      val school:String = "YelloRiwer"
​
  def main(args: Array[String]): Unit = {
    val alice = new Student("alice",20)
    val bob = new Student("bob",23)
​
    alice.printInfo()
    bob.printInfo()
  }
}

运行结果:

复制代码
alice 20 YelloRiwer
bob 23 YelloRiwer

Scala基本操作:

IDEA快捷键: 快速格式化: Ctrl + Alt + L

2.2变量和常量(重点)

常量:在程序执行的过程中,其值不会被改变的变量

0)回顾:Java 变量和常量语法

复制代码
变量类型 变量名称 = 初始值 
int a = 10
​
final 常量类型 常量名称 = 初始值 
final int b = 20

1)Scala基本语法

复制代码
var 变量名 [: 变量类型] = 初始值  
var i:Int = 10
​
val 常量名 [: 常量类型] = 初始值 
val j:Int = 20

注意:能用常量的地方不用变量


chapter02
Text02
变量与常量
复制代码
package chapter02

import chapter01.Student

object Test02_Variable {
  def main(args: Array[String]): Unit = {
    // 声明一个变量的通用语法
    var a: Int = 10

    //(1)声明变量时,类型可以省略,编译器自动推导,即类型推导
    var a1 = 10
    val b1 = 23

    //(2)类型确定后,就不能修改,说明Scala是强数据类型语言。
    var a2 = 15    // a2类型为Int
//    a2 = "hello"

    //(3)变量声明时,必须要有初始值
//    var a3: Int

    //(4)在声明/定义一个变量时,可以使用var或者val来修饰,var修饰的变量可改变,val修饰的变量不可改。
    a1 = 12
//    b1 = 25

    var alice = new Student("alice", 20)
    alice = new Student("Alice", 20)
    alice = null
    val bob = new Student("bob", 23)
    bob.age = 24
    bob.printInfo()
//    bob = new Student("bob", 24)
  }
}
Text03
标识符
复制代码
package chapter02

object Test03_Identifier {
  def main(args: Array[String]): Unit = {
    //(1)以字母或者下划线开头,后接字母、数字、下划线
    val hello: String = ""
    var Hello123 = ""
    val _abc = 123

//    val h-b = ""
//    val 123abc = 234

    //(2)以操作符开头,且只包含操作符(+ - * / # !等)
    val -+/% = "hello"
    println(-+/%)

    //(3)用反引号`....`包括的任意字符串,即使是Scala关键字(39个)也可以
    val `if` = "if"
    println(`if`)
  }
}
Text04
字符串拼接
复制代码
package chapter02

object Test04_String {
  def main(args: Array[String]): Unit = {
    //(1)字符串,通过+号连接
    val name: String = "alice"
    val age: Int = 18
    println(age + "岁的" + name + "在尚硅谷学习")

    // *用于将一个字符串复制多次并拼接
    println(name * 3)

    //(2)printf用法:字符串,通过%传值。
    printf("%d岁的%s在尚硅谷学习", age, name)
    println()

    //(3)字符串模板(插值字符串):通过$获取变量值
    println(s"${age}岁的${name}在尚硅谷学习")

    val num: Double = 2.3456
    println(f"The num is ${num}%2.2f")    // 格式化模板字符串
    println(raw"The num is ${num}%2.2f")

    // 三引号表示字符串,保持多行字符串的原格式输出
    val sql = s"""
       |select *
       |from
       |  student
       |where
       |  name = ${name}
       |and
       |  age > ${age}
       |""".stripMargin
    println(sql)
  }
}

println() printf() System.out.println()

上面三个都可以输出内容

println和System.out.println一样

printf("%d岁的%s在尚硅谷学习", age, name)

println(s"")#字符串模板

println(f"")#快速格式化字符串

println(raw"")#原始格式输出

Text05
键盘输入
复制代码
package chapter02

import scala.io.StdIn

object Test05_StdIn {
  def main(args: Array[String]): Unit = {
    // 输入信息
    println("请输入您的大名:")
    val name: String = StdIn.readLine()
    println("请输入您的芳龄:")
    val age: Int = StdIn.readInt()

    // 控制台打印输出
    println(s"欢迎${age}岁的${name}来到尚硅谷学习")
  }
}
Text06
读写文件
复制代码
package chapter02

import java.io.{File, PrintWriter}
import scala.io.Source

object Test06_FileIO {
  def main(args: Array[String]): Unit = {
    // 1. 从文件中读取数据
    Source.fromFile("src/main/resources/test.txt").foreach(print)

    // 2. 将数据写入文件
    val writer = new PrintWriter(new File("src/main/resources/output.txt"))
    writer.write("hello scala from java writer")
    writer.close()
  }
}
Text07
文件类型
复制代码
package chapter02

import chapter01.Student

object Test07_DataType {
  def main(args: Array[String]): Unit = {
    // 1. 整数类型
    val a1: Byte = 127
    val a2: Byte = -128

//    val a2: Byte = 128    // error

    val a3 = 12    // 整数默认类型为Int
    val a4: Long = 1324135436436L    // 长整型数值定义

    val b1: Byte = 10
    val b2: Byte = 10 + 20
    println(b2)

//    val b3: Byte = b1 + 20
    val b3: Byte = (b1 + 20).toByte
    println(b3)

    // 2. 浮点类型
    val f1: Float = 1.2345f
    val d1 = 34.2245

    // 3. 字符类型
    val c1: Char = 'a'
    println(c1)

    val c2: Char = '9'
    println(c2)

    // 控制字符
    val c3: Char = '\t'    // 制表符
    val c4: Char = '\n'    // 换行符
    println("abc" + c3 + "def")
    println("abc" + c4 + "def")

    // 转义字符
    val c5 = '\\'    // 表示\自身
    val c6 = '\"'    // 表示"
    println("abc" + c5 + "def")
    println("abc" + c6 + "def")

    // 字符变量底层保存ASCII码
    val i1: Int = c1
    println("i1: " + i1)
    val i2: Int = c2
    println("i2: " + i2)

    val c7: Char = (i1 + 1).toChar
    println(c7)
    val c8: Char = (i2 - 1).toChar
    println(c8)

    // 4. 布尔类型
    val isTrue: Boolean = true
    println(isTrue)

    // 5. 空类型
    // 5.1 空值Unit
    def m1(): Unit = {
      println("m1被调用执行")
    }

    val a: Unit = m1()
    println("a: " + a)

    // 5.2 空引用Null
//    val n: Int = null    // error
    var student: Student = new Student("alice", 20)
    student = null
    println(student)

    // 5.3 Nothing
    def m2(n: Int): Int = {
      if (n == 0)
        throw new NullPointerException
      else
        return n
    }


    val b: Int = m2(2)
    println("b: " + b)
  }
}
Text08
自动类型转换:
复制代码
package chapter02

object Test08_DataTypeConversion {
  def main(args: Array[String]): Unit = {

    // 1. 自动类型转换
    //    (1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算。
    val a1: Byte = 10
    val b1: Long = 2353
    val result1: Long = a1 + b1
    val result11: Int = (a1 + b1.toInt) // 强转

    //    (2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动类型转换。
    val a2: Byte = 10
    val b2: Int = a2
    //    val c2: Byte = b2    // error

    //    (3)(byte,short)和char之间不会相互自动转换。
    val a3: Byte = 10
    val b3: Char = 'b'
    //    val c3: Byte = b3    // error
    val c3: Int = b3
    println(c3)

    //    (4)byte,short,char他们三者可以计算,在计算时首先转换为int类型。
    val a4: Byte = 12
    val b4: Short = 25
    val c4: Char = 'c'
    val result4: Int = a4 + b4
    val result44: Int = a4 + b4 + c4
    println(result44)

    // 2. 强制类型转换
    //    (1)将数据由高精度转换为低精度,就需要使用到强制转换
    val n1: Int = -2.9.toInt
    println("n1: " + n1)

    //    (2)强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
    val n2: Int = 2.6.toInt + 3.7.toInt
    val n3: Int = (2.6 + 3.7).toInt
    println("n2: " + n2)
    println("n3: " + n3)

    // 3. 数值类型和String类型的转换
    // (1) 数值转String
    val n: Int = 27
    val s: String = n + ""
    println(s)

    // (2) String转数值
    val m: Int = "12".toInt
    val f: Float = "12.3".toFloat
    val f2: Int = "12.3".toDouble.toInt
    println(f2)
  }
}
Text09
复制代码
package chapter02

/*
128: Int类型,占据4个字节,32位
原码 0000 0000 0000 0000 0000 0000 1000 0000
补码 0000 0000 0000 0000 0000 0000 1000 0000

截取最后一个字节,Byte
得到补码 1000 0000
表示最大负数 -128

130: Int类型,占据4个字节,32位
原码 0000 0000 0000 0000 0000 0000 1000 0010
补码 0000 0000 0000 0000 0000 0000 1000 0010

截取最后一个字节,Byte
得到补码 1000 0010
对应原码 1111 1110
-126
 */

object Test09_Problem_DataTypeConversion {
  def main(args: Array[String]): Unit = {
    var n: Int = 130
    val b: Byte = n.toByte
    println(b)
  }
}
范围数据循环(Until)

1)基本语法

复制代码
for(i <- 1 until 3) {

 print(i + " ")

}

println()

(1)这种方式和前面的区别在于 i 是从 1 到 3-1

(2)即使前闭合后开的范围

2)案例实操

需求:输出 5 句 "宋宋,告别海狗人参丸吧"

复制代码
object TestFor {
    
 def main(args: Array[String]): Unit = {
     
 for(i <- 1 until 5 + 1){
     
 println("宋宋,告别海狗人参丸吧" + i)
     
		 }
	 }
}
循环守卫

1)基本语法

复制代码
for(i <- 1 to 3 if i != 2) {

 print(i + " ")

}

println()

说明:

(1)循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为 true 则进入循环

体内部,为 false 则跳过,类似于 continue。

(2)与上面的代码等价

复制代码
for (i <- 1 to 3){

if (i != 2) {

print(i + " ")

	}	

}

2)案例实操

需求:输出 1 到 5 中,不等于 3 的值

复制代码
object TestFor {

 def main(args: Array[String]): Unit = {

 for (i <- 1 to 5 if i != 3) {

 println(i + "宋宋")

		 }

	 }

}
循环步长

1)基本语法

复制代码
for (i <- 1 to 10 by 2) {

 println("i=" + i)

}

说明:by 表示步长

2)案例实操

需求:输出 1 到 10 以内的所有奇数 by表示步长

复制代码
for (i <- 1 to 10 by 2) {

println("i=" + i)

}

输出结果

复制代码
i=1

i=3

i=5

i=7

i=9
嵌套循环

1)基本语法

复制代码
for(i <- 1 to 3; j <- 1 to 3) {

 println(" i =" + i + " j = " + j)

}

说明:没有关键字,所以范围后一定要加;来隔断逻辑

2)基本语法

上面的代码等价

复制代码
for (i <- 1 to 3) {

 for (j <- 1 to 3) {

 println("i =" + i + " j=" + j)

 	}

}
引入变量

1)基本语法

复制代码
for(i <- 1 to 3; j = 4 - i) {

 println("i=" + i + " j=" + j)

}

说明:

(1)for 推导式一行中有多个表达式时,所以要加 ; 来隔断逻辑

(2)for 推导式有一个不成文的约定:当 for 推导式仅包含单一表达式时使用圆括号,

当包含多个表达式时,一般每行一个表达式,并用花括号代替圆括号,如下

复制代码
for {

 i <- 1 to 3

j = 4 - i

} {

 println("i=" + i + " j=" + j)

}

2)案例实操

上面的代码等价于

复制代码
for (i <- 1 to 3) {

 var j = 4 - i

 println("i=" + i + " j=" + j)

}
循环返回值

1)基本语法

复制代码
val res = for(i <- 1 to 10) yield i

println(res)

说明:将遍历过程中处理的结果返回到一个新 Vector 集合中,使用 yield 关键字。

注意:开发中很少使用。

2)案例实操

需求:将原数据中所有值乘以 2,并把数据返回到一个新的集合中。

复制代码
object TestFor {

 def main(args: Array[String]): Unit = {

 var res = for(i <-1 to 10) yield {

 i * 2

	 }

 println(res)

	 }

}

输出结果:

复制代码
Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
倒序打印
复制代码
1)说明:如果想倒序打印一组数据,可以用 reverse。
2)案例实操:
需求:倒序打印 10 到 1
for(i <- 1 to 10 reverse){
 println(i)
}
While和do...While循环控制

While和do...While的使用和Java语言中用法相同

While循环控制

1)基本语法

复制代码
	循环变量初始化;
while (循环条件) {

 循环体(语句)

 循环变量迭代

}

说明:

(1)循环条件是返回一个布尔值的表达式

(2)while 循环是先判断再执行语句

(3)与 for 语句不同,while 语句没有返回值,即整个 while 语句的结果是 Unit 类型()

(4)因为 while 中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免

的使用变量,而变量需要声明在 while 循环的外部,那么就等同于循环的内部对外部的变量

造成了影响,所以不推荐使用,而是推荐使用 for 循环。

2)案例实操

需求:输出 10 句 "宋宋,喜欢海狗人参丸"

复制代码
object TestWhile {
 
 def main(args: Array[String]): Unit = {
 var i = 0
 while (i < 10) {
 println("宋宋,喜欢海狗人参丸" + i)
 i += 1
		 }
	 }
}
do...while循环控制

1)基本语法

复制代码
 循环变量初始化;
do{
    循环体(语句)
 循环变量迭代
 } while(循环条件)

说明

(1)循环条件是返回一个布尔值的表达式

(2)do..while 循环是先执行,再判断

2)案例实操

需求:输出 10 句 "宋宋,喜欢海狗人参丸"

复制代码
object TestWhile {
 def main(args: Array[String]): Unit = {
 var i = 0
 do {
 println("宋宋,喜欢海狗人参丸" + i)
 i += 1
		 } while (i < 10)
	 }
}
循环中断

1)基本说明

Scala 内置控制结构特地去掉了 break continue ,是为了更好的适应函数式编程,推

荐使用函数式的风格解决break和continue的功能,而不是一个关键字。Scala中使用breakable

控制结构来实现 break 和 continue 功能。

2)案例实操

需求 1:采用异常的方式退出循环

复制代码
def main(args: Array[String]): Unit = {
 
    try {
 		for (elem <- 1 to 10) {
			 println(elem)
			 if (elem == 5) throw new RuntimeException
             }
 }catch {
 case e =>
 }
 println("正常结束循环")
}

需求 2:采用 Scala 自带的函数,退出循环

复制代码
import scala.util.control.Breaks
def main(args: Array[String]): Unit = {
	 Breaks.breakable(
		 for (elem <- 1 to 10) {
			 println(elem)
			 if (elem == 5) Breaks.break()
			 }
		 )
	 println("正常结束循环")
}

需求 3:对 break 进行省略

复制代码
import scala.util.control.Breaks._
object TestBreak {
 def main(args: Array[String]): Unit = {
 
	 breakable {
		 for (elem <- 1 to 10) {
			 println(elem)
 			if (elem == 5) break
		 }
	 }
 
 println("正常结束循环")
 	}
}

需求 4:循环遍历 10 以内的所有数据,奇数打印,偶数跳过(continue)

复制代码
object TestBreak {
 	def main(args: Array[String]): Unit = {
		 for (elem <- 1 to 10) {
 			if (elem % 2 == 1) {
				 println(elem)
			 } else {
				 println("continue")
			 }
		 }
	 }
}
多重循环

1)基本说明

(1)将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for,while,do...while

均可以作为外层循环和内层循环。【建议一般使用两层,最多不要超过 3

(2)设外层循环次数为 m 次,内层为 n 次,则内层循环体实际上需要执行 m*n 次。

2)案例实操

需求:打印出九九乘法表

复制代码
object TestWhile {
 	def main(args: Array[String]): Unit = {
 		for (i <- 1 to 9) {
			 for (j <- 1 to i) {
				 print(j + "*" + i + "=" + (i * j) + "\t")
			 }
			 println()
		 }
	 }
}

输出结果:

相关推荐
喝醉酒的小白7 分钟前
Elasticsearch(ES)监控、巡检及异常指标处理指南
大数据·elasticsearch·搜索引擎
lucky_syq23 分钟前
Spark和Hadoop之间的区别
大数据·hadoop·spark
LuH112430 分钟前
【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo
论文阅读·笔记
m0_748256782 小时前
WebGIS实战开源项目:智慧机场三维可视化(学习笔记)
笔记·学习·开源
红色的山茶花2 小时前
YOLOv9-0.1部分代码阅读笔记-loss.py
笔记
胡西风_foxww5 小时前
【es6复习笔记】Promise对象详解(12)
javascript·笔记·es6·promise·异步·回调·地狱
吉大一菜鸡10 小时前
FPGA学习(基于小梅哥Xilinx FPGA)学习笔记
笔记·学习·fpga开发
WTT001111 小时前
2024楚慧杯WP
大数据·运维·网络·安全·web安全·ctf
CCSBRIDGE13 小时前
Magento2项目部署笔记
笔记