Scala_Day01
文章目录
什么是Scala
Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于Java平台(Java虚拟机)并兼容现有的Java程序。
java与scala之间的关系
.java文件 -> 使用javac命令 -> 运行在jvm虚拟机上 -> 变成.class字节码文件
.scala文件 -> 使用scalac命令 -> 运行在jvm虚拟机上 -> 变成.class字节码文件
scala的创始人是谁
马丁.奥德斯基
我们为什么要学习scala
- 优雅:这是框架设计师第一个要考虑的问题,框架的用户是应用开发程序员,API是否优雅直接影响用户体验。
- 速度快:Scala 语言表达能力强,一行代码抵得上Java多行开发速度快;Scala是静态编译的,所以和JRuby,Groovy 比起来速度会快很多。
- 能融合到 Hadoop生态圈:Hadoop 现在是大数据事实标准,Spark并不是要取代 Hadoop而是要完善Hadoop生态。JVM 语言大部分可能会想到 Java,但Java出来的 API 太丑,或者想实现一个优雅的 API 太费劲
Scala语言的发展史
-
联邦理工学院的马丁·奥德斯基(Martin Odersky)于2001年开始设计Scala。
-
马丁·奥德斯基是编译器及编程的狂热爱好者,长时间的编程之后,希望发明一种语言,能够让写程序这样的基础工作变得高效,简单。所以当接触到JAVA语言后,对JAVA这门便携式,运行在网络,且存在垃圾回收的语言产生了极大的兴趣,所以决定将函数式编程语言的特点融合到JAVA中,由此发明了两种语言(Pizza & Scala)
-
Pizza和Scala极大地推动了Java编程语言的发展。
-
JDK5.0 的泛型、增强for循环、自动类型转换等,都是从Pizza引入的新特性。
-
JDK8.0 的类型推断、Lambda表达式就是从Scala引入的特性。
Scala语言的特性
-
Scala是面向对象的
Scala是一种纯粹的面向对象语言,每一个值都是对象。对象的数据类型以及行为由类和特征来描述,类抽象机制的扩展通过两种途径实现,一种是子类继承,另一种是混入机制,这两种途径都能够避免多重继承的问题。
-
Scala是函数式编程的
Scala也是一种函数式语言,其函数可以作为值来使用。Scala提供了轻量级的语法用于定义匿名函数,支持高阶函数,允许嵌套多层函数,并支持柯里化。
-
Scala是静态类型的
Scala具备类型系统,通过编译时检查,保证代码的安全性和一致性。类型系统支持的特性包括泛型类、注释、类型上下限约束、类别和抽象类型作为对象成员、复合类型、引用自己时显示指定类型、视图、多态方法。
-
Scala是可扩展的
在实际开发中,某个特定领域的应用程序开发往往需要特定领域的语言扩展。Scala提供了许多独特的语言机制,它以库的方式能够轻易无缝添加新的语言结构。
-
Scala是可以交互操作的
Scala旨在与流行的Java Runtime Environment(JRE)进行良好的交互操作。Scala用scalac编译器把源文件编译成Java的class文件(即在JVM上运行的字节码)。我们可以从Scala中调用所有的Java类库,也同样可以从Java应用程序中调用Scala的代码。
面向对象和面向函数
-
定义
- 函数式编程:以函数思维做为核心,在这种思维的角度去思考问题。这种编程最重要的基础是λ演算,接受函数当作输入和输出。
- 面向对象编程:这种编程是把问题看作由对象的属性与对象所进行的行为组成。基于对象的概念,以类作为对象的模板,把类和继承作为构造机制,以对象为中心,来思考并解决问题。
-
缺点
- 函数式编程:所有的数据都是不可以改变的,严重占据运行资源,导致运行速度也不够快。
- 面向对象编程:为了编写可以重用的代码导致许多无用代码的产生,并且许多人为了面向对象而面向对象导致代码给后期维护带来很多麻烦。
-
优点
-
函数式编程:支持闭包和高阶函数,闭包是一种可以起函数的作用并可以如对象般操作的对象;而高阶函数是可以以另一个函数作为输入值来进行编程。支持惰性计算,这就可以在求值需要表达式的值得时候进行计算,而不是固定在变量时计算。还有就是可以用递归作为控制流程。函数式编程所编程出来的代码相对而言少很多,而且更加简洁明了。
-
面向对象编程:面向对象有三个主要特征,分别是封装性、继承性和多态性。类的说明展现了封装性,类作为对象的模板,含有私有数据和公有数据,封装性能使数据更加安全依赖的就是类的特性,使得用户只能看到对象的外在特性,不能看到对象的内在属性,用户只能访问公有数据不能直接访问到私有数据。类的派生功能展现了继承性,继承性是子类共享父类的机制,但是由于封装性,继承性也只限于公有数据的继承(还有保护数据的继承),子类在继承的同时还可以进行派生。而多态性是指对象根据接收的信息作出的行为的多态,不同对象接收同一信息会形成多种行为。
-
注释
Scala注释使用和Java完全一样。
注释是一个程序员必须要具有的良好编程习惯。将自己的思想通过注释先整理出来,再用代码去体现。
基本语法
单行注释://
多行注释:/* */
文档注释: /** */
常量和变量
常量:在程序执行的过程中,其值不会被改变的变量
回顾:Java变量和常量语法
变量类型 变量名称 = 初始值
int a = 10
final常量类型 常量名称 = 初始值
final int b = 20
基本语法
var 变量名 [: 变量类型] = 初始值
var i:Int = 10
val 常量名 [: 常量类型] = 初始值
val j:Int = 20
注意:能用常量的地方不用变量
验证object中调用的方法都是静态的方法
package com.shujia
class Demo01HelloWorldScala {
/**
* 在Scala中并没有static关键字,所以在class中定义的方法或者是变量都是成员的方法或属性
* 所以在class中定义的main方法就是普通的成员方法,需要通过类的对象进行"调用"
* 所以如果想要直接通过“类对象”调用main方法,则需要让它作为静态方法出现
* main方法是保留的一个方法,不能放在class中定义
*/
// def main(args: Array[String]): Unit = {
// System.out.println("HelloWorld Scala!")
// }
def printHello(): Unit = {
println("Hello Scala")
}
}
/**
* 在object中定义的所有的属性和方法都是静态的
* 在这里定义的Demo01HelloWorldScala实际上可以成为“类对象”
*/
object Demo01HelloWorldScala {
def printWorld(): Unit = {
println("World Scala")
}
/**
* Scala中函数的定义:
* def 声明一个函数
* main 方法名
* args 参数名
* Array[String] 参数类型
* Unit 返回值类型,相当于Java中的void,表示没有返回值
* {} 函数体
*
* Scala中其实也有访问权限修饰符,但一般不用
*/
def main(args: Array[String]): Unit = {
// System.out.println("HelloWorld Scala!") // Java的打印风格
println("HelloWorld Scala!") // Scala的打印风格
// 调用printHello:需要通过new类的对象进行调用
new Demo01HelloWorldScala().printHello()
// 调用printWorld:直接通过类对象进行调用
Demo01HelloWorldScala.printWorld()
}
}
Scala基础语法
package com.shujia
import java.io.{BufferedReader, FileReader}
import java.sql.{Connection, DriverManager, PreparedStatement, ResultSet}
import scala.io.{BufferedSource, Source, StdIn}
object Demo02Base {
def main(args: Array[String]): Unit = {
/**
* Scala中的变量与常量
* val:不可变的
* var:可变的(可以任意赋值修改)
*/
val i = 10 // 类型可以省略,Scala会自动推断
val ii: Int = 10
// i = 100 // val 修饰的变量不可以改变
var j = 20
var jj: Int = 20
j = 200
val intArr: Array[Int] = Array[Int](1, 2, 3, 4)
println(intArr(1))
intArr(1) = 22
println(intArr(1))
/**
* 这里val修饰的变量不可变,实际上是指变量的引用不可变
* 能使用val的时候就尽量使用
*/
// Scala中的数据类型
/**
* 所有类型都是Any的子类
* Any有两个直接子类:AnyVal和AnyRef
* AnyVal是任何值类型的父类
* AnyRef是任何引用类型的父类
*
* 值类型:Byte、Short、Int、Long、Float、Double、Boolean、Char
*/
val byte: Byte = 10
val short: Short = 100
val int: Int = 1000000
val long: Long = 1000000000000L
val float: Float = 1.2345678F
val double: Double = 1.23456781011111111D
val bool1: Boolean = true
val bool2: Boolean = false
val char: Char = 'a'
// 类型的转换
// 在Scala中需要转成什么类型,直接to对应的类型即可
val char2int: Int = 'a' // 小转大 自动完成
println(char2int)
val tmpInt: Int = 98
val int2char: Char = tmpInt.toChar // 大转小 需要手动调用
println(int2char)
// 字符串类型
val str1: String = "abcdefg"
println(str1)
val str2: String = "12345"
println(Integer.parseInt(str2))
println(str2.toInt) // Scala中有很多对象的方法是通过隐式转换加上去的
// 字符串常用的方法:substring、split、大小写转换
val str3: String = "Java,Python|Scala"
println(str3.substring(5, 11))
println(str3.split(",|\\|").toList)
// 省略形式
// 对象在调用方法时可以省略 . 以及 括号 直接使用空格分割即可
println(str3 split ",|\\|" toList)
// Scala 中的运算符
// 算术运算符
val i1: Int = 10
val i2: Int = 3
println(i1 + i2)
println(i1 - i2)
println(i1 * i2)
println(i1 / i2) // 注意精度
println(i1.toDouble / i2) // 注意精度
println(i1 % i2)
// 比较运算符
// Scala中直接可以使用 == 来比较两个引用变量的值相不相等 不需要使用equals
// > >= < <= == !=
// SQL:<>、<=>
// SparkSQL DSL:===、=!=
// 位运算符:<< >>
println(8 >> 2) // 00001000 >> 2 -> 00000010
println(2 << 2) // 00000010 << 2 -> 00001000
println(8 & 3) // 0 00001000 00000011
println(8 | 3) // 11 00001011
// 逻辑运算符
println(true && false) // 逻辑与
println(true || false) // 逻辑或
println(true ^ false) // 异或
println(!false) // 取反
println("##################################################")
println("#" * 50)
println("#".*(50))
println(1.+(2))
println(1 + 2)
// 选择循环结构
// 选择结构:if、else if、else
// 输入一个年龄age,判断是否成年
// print("请输入一个年龄:")
// val age: Int = StdIn.readInt()
val age: Int = 20
if (age < 0 || age > 200) {
println("年龄有误")
} else if (age < 18) {
println("未成年")
} else {
println("成年")
}
// 选择结构可以有返回值
val i3: Int = 10
val i4: Int = 5
val i5: Int = if (i3 > i4) {
i3
} else {
i4
}
println("return 之后的代码")
// match 类似Java中的switch
// 也可以返回一个值
val p: Int = 30
val i6: AnyVal = p match {
case 0 =>
println("p的值为0")
0
case 1 =>
println("p的值为1")
1
case 2 =>
println("p的值为2")
2
case 3 =>
println("p的值为3")
3
case _ => // 类似Java中的default
println("其他值")
-1.123
}
println(i6)
// 循环结构:while do、do while、for each
// 统计1~100的和
// while do
var cnt: Int = 1
var sum: Int = 0
while (cnt <= 100) {
sum += cnt
cnt += 1
}
println(sum)
// do while
var cnt2: Int = 1
var sum2: Int = 0
do {
sum2 += cnt2
cnt2 += 1
} while (cnt2 <= 100)
println(sum2)
// Scala中的for循环主要用于遍历集合 类似Python中的for
// Scala中并没有fori
val arr: Array[String] = "Hadoop,Hive,HBase".split(",")
println(arr)
for (s: String <- arr) {
println(s)
}
// Scala中函数式编程的写法
arr.foreach(println)
// 如果非得使用下标遍历元素 可以使用for 结合 to、until、range进行遍历
for (i <- 0 to arr.length - 1) {
println(arr(i))
}
for (i <- 0 until arr.length) {
println(arr(i))
}
for (i <- Range(0, arr.length, 1)) {
println(arr(i))
}
for (i <- arr.indices) {
println(arr(i))
}
// Scala中常见的操作:读写文件、操作MySQL
// 读文件
// Java的方式
val br: BufferedReader = new BufferedReader(new FileReader("scala/data/stu/students.txt"))
var line: String = br.readLine()
while (line != null) {
println(line)
line = br.readLine()
}
println("$" * 50)
// Scala的方式
val bs: BufferedSource = Source
.fromFile("scala/data/stu/students.txt")
val iter: Iterator[String] = bs.getLines()
for (elem <- iter) {
println(elem)
}
println("#" * 50)
// 链式调用
Source
.fromFile("scala/data/stu/students.txt")
.getLines()
.foreach(println)
// Scala写文件没有特殊的方式,使用Java的那一套即可
// 读取MySQL中的数据:实际上也没有特殊的方式,也是使用Java的那一套
// 建立连接
val conn: Connection = DriverManager.getConnection("jdbc:mysql://rm-bp1h7v927zia3t8iwho.mysql.rds.aliyuncs.com:3307/stu025", "stu025", "123456")
val clazz: String = "文科一班"
val sql1: String = "select id,name,age,gender from students where clazz = ?"
// Scala中有一种特殊的方式可以让SQL换行
val sql2: String =
"""
|select id
| ,name
| ,age
| ,gender
|from students
|where clazz = ?
|""".stripMargin
// 创建statement
val pSt: PreparedStatement = conn.prepareStatement(sql2)
// 设置参数
pSt.setString(1, clazz)
// 执行查询
val rs: ResultSet = pSt.executeQuery()
// 遍历获取数据
while (rs.next()) {
val id: Int = rs.getInt("id")
val name: String = rs.getString("name")
val age: Int = rs.getInt("age")
val gender: String = rs.getString("gender")
val _clazz: String = "文科一班"
// println(id + "," + name + "," + age + "," + gender)
// Scala格式化字符串
println(s"$id,$name,$age,$gender,${_clazz}")
}
// 关闭连接
rs.close()
pSt.close()
conn.close()
}
}