第一章.Scala入门
1.概述
为什么学习Scala
- Spark-新一代内存级大数据计算框架,是大数据的重要内容
- Spark就是使用Scala编写的
- Spark的兴起,带动Scala语言的发展
一.Scala发展历史
- 创始人:马丁.奥德斯基(Martin Odersky),将函数式编程语言的特点融入到java中,发明了Scala和Pizza两种语言
- jdk5.0 的泛型,for循环增强,自动类型转换等,都是从Pizza 引入的新特性。
- jdk8.0 的类型推断,Lambda表达式就是从Scala引入的特性。
二.Scala与Java关系
三.Scala语言特点
- Scala是一门以Java虚拟机(JVM)为运行环境,并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言
- Scala是一门多范式的编程语言,Scala支持面向对象和函数式编程
- Scala的源代码(.scala)会被编译成Java字节码(.class).然后运行于JVM之上,并可以调用现有的Java类库,实现两种语言的无缝对接
- Scala单作为一门语言来看,非常的简洁高效
四.Scala环境搭建
- 确保JDK安装成功
- 下载对应的Scala安装文件scala-2.11.8.zip,并解压
- 配置Scala的环境变量
- 在Idea中安装对应的scala插件
五.HelloWorld案例
- 打开idea,新建一个maven项目(scala-study)
- 默认情况下,maven不支持scala的开发,需要引入scala的相关类库
- 创建项目的源文件目录,并右键->make directory as-> source root
- 默认情况下,会使用maven进行编译,则会报错,需要取消相关设置
- 新建一个包com.atguigu.chapter01,创建一个helloword
package com.atguigu.chapter01
/*
*java中的main方法的语法: public static void main(String[] args){...}
* scala object中所有的属性和方法都是类似java static修饰的
* scala class中所有的属性和方法都是类似java 非static
* Unit相当于java的void
* Array代表字符串数组
* def 是defined的缩写,是方法的标识符
* */
object HelloWord {
def main(args: Array[String]): Unit = {
println("hello word")
}
}
第二章.变量和数据类型
1.注释
package com.atguigu.chapter02
object $01_Command {
/**
* java的注释:
* 单行注释: //
* 多行注释: /*..*/
* 文档注释: /** ..*/
* scala注释:
* 单行注释:
* 多行注释: /*..*/
* 文档注释: /** ..*/
*/
def main(args:Array[String]): Unit ={
//单行注释
val name = "zhangsan"
/*
* 多行注释
* */
val age = 20
}
}
2.标识符的命名规范
package com.atguigu.chapter02
/**
* java标识符的命名规范,必须是字母,数字,下划线,$,首字母不能是数字
* scala标识符的命名规范,必须是字母,数字,下划线,$,特殊符号,首字母不能是数字
* scala标识符的特殊符号是scala内部使用的
* 工作中,定义变量的时候依然采用驼峰原则
*/
object $02_ParamDefinedOperator {
def main(args:Array[String]): Unit={
var $name = "xxx"
var + = 10
println(+)
}
}
3.变量
package com.atguigu.chapter02
/*
* java定义变量: 类型 变量名 = 值
* scala定义变量的语法: val/var 变量名:类型 =值
* val与var的区别:
* val修饰的变量类似java final修饰的,不能给变量重新赋值
* var修饰的变量类似java 非final修饰的,可以给变量重新赋值
* scala定义变量的时候可以省略变量类型,省略之后scala会自动推断变量类型
* scala中如果一行只写一个语句,分号可以省略,如果一行写多个语句,分号不能生=省略
*/
object $03_ParamDefined {
def main(args:Array[String]): Unit ={
val name:String = "zhangsan"
var age:Int = 20
println(name)
println(age)
//name = "lisi"
age = 100
println(age)
val address = "shenzhen"
print(address)
}
}
4.字符串输出
package com.atguigu.chapter02
object $04_String {
/**
* java获取字符串的方式:
* 1.通过new的方式: new String("xxx")
* 2.直接"": "xxx"
* 3.通过+拼接: "aa" + "bb"
* 4.可以通过一些方法: substring,toString
*
* scala获取字符串的方式:
* 1.通过new的方式: new String("xxx")
* 2.直接 "": "xxx"
* 3.拼接
* 1.通过+拼接:"aa" + "bb"
* 2.通过插值表达式: s"${变量名/表达式/值}"
* 4.可以通过一些方法: substring,toString
* 5.通过三引号的方式: """..."""
*/
def main(args:Array[String]):Unit={
//1.通过new的方式创建
val name = new String("hello")
println("===============================")
println(name)
//2.直接""
val sex = "man"
println("===============================")
println(sex)
//3.通过+拼接
val namesex = name + "_" +sex
println("===============================")
println(namesex)
//4.通过插值表达式
val namesex2 = s"${name}_${sex} ${2+1} ${3}"
println("===============================")
println(namesex2)
//5.可以通过一些方法:substring,toString
val hello = namesex.substring(4)
println("===============================")
println(hello)
println("===============================")
val host = "hadoop102"
val port = 8020
val url = "http://%s:%d/xx/xx/xx"
//%s: 字符串占位符
//%d: 整数占位符
//%f: 浮点型占位符
val url2 = url.format(host,port)
println("===============================")
println(url2)
//三引号
val sql = "select " +
"id,"+
"name,"+
"age,"+
"sex"+
" from person a"+
" left join student b"+
"on a.id = b.id"
println("===============================")
println(sql)
val table = "person"
val sql2 =
s"""
|select
| a.id
| b.name
| b.age
| a.sex
| from ${table} a left join student b
| on a.id = b.id
|""".stripMargin
println("===============================")
println(sql2)
val json = "{\"name\":\"lisi\",\"age\":20}"
println("===============================")
println(json)
val json2 = """{"name":"lisi","age":20}"""
println("===============================")
println(json2)
}
}
5.键盘输入
package com.atguigu.chapter02
import scala.io.{Source, StdIn}
object $05_StdIn {
//从控制台读取数据: StdIn.readLine()/readInt/readChar/..
//读取本地文件: Source.fromFile(path).getLines()
def main(args:Array[String]):Unit ={
val line = StdIn.readLine("请输入一行语句:")
println(line)
println("==========================")
println(Source.fromFile("d:/test.csv").getLines().toList)
}
}
6.数据类型
package com.atguigu.chapter02
object $06_DataType {
/**
* java的数据类型
* 1.基本数据类型
* byte,short,int,long,float,double,char,boolean
* 2.引用类型
* string,集合,数组,其他class
*scala是完全面向对象的语言
* Any: 所有类的父类
* AnyVal:值类型
* Byte,Short,Int,Long,Float,Double,Char,Boolean
* Unit:相当于java的void,有一个实例()
* Stringops:scala针对 java string的扩展
* AnyRef:引用类型
* String,java集合/数组/class,scala的集合/数组/class
* Null:所有引用类型的子类,有一个实例null,一般用于给引用类型变量赋予初始值,在赋予初始值的时候必须指定变量类型
* Nothing: 所有类型的子类
*
*/
def main(args:Array[String]): Unit={
val u = ()
println(u)
println("=====================")
var name:String = null
println(name)
name = "lisi"
println("=====================")
println(name)
//val n = new Nothing
//println(n)
}
}
7.类型转换
package com.atguigu.chapter02
object $07_TypeCover {
/**
* 数字与数字的转换
* 低精度转高精度[Int->Long]:自动转换
* 高精度转低精度[Long->Int]:toXXX方法
* 数字和字符串的转换
* 字符串转数字:toXXX方法
* 数字转字符串:拼接,toString
*/
def main(args:Array[String]): Unit={
//低精度转高精度[Int->Long]:自动转换
val a:Int = 10
val b:Long = a
println(b)
//高精度转低精度[Long->Int]
val c:Long = 10L
val d:Int = c.toInt
println(d)
//字符串转数字
val s = "10"
val e:Int = s.toInt
println(e)
val f:Double = s.toDouble
println(f)
}
}
第三章.运算符
package com.atguigu.chapter03
/**
* java的操作符:
* 算术运算符: + - * / ++ -- %
* 逻辑运算符: && || !
* 比较运算符: < > <= >= != ==
* 赋值运算符: += -= *= /=
* 位运算符: << >> >>> $ |
* 三元运算符: 布尔表达式?true:false
* scala没有三元运算符,++ --
* 算术运算符: + - * / %
* 逻辑运算符: && || !
* 比较运算符: < > <= >= != ==
* 赋值运算符: += -= *= /=
* 位运算符: << >> >>> $ |
* scala的操作符是一个个的方法
* scala的方法的调用有两种方式:
* 1.对象.方法名(参数值,...)
* 2.对象 方法名 (参数值,...) [如果方法只有一个参数,参数的()可以忽略]
*
*/
object $01_Operator {
def m1(x:Int):Int = x + 10
def main(args:Array[String]):Unit ={
val d = 1.+(2)
println(d)
val f = 1+2
println(f)
val g = $01_Operator.m1(10)
println(g)
val h = $01_Operator m1 20
println(h)
}
}
第四章.流程控制
1.块表达式
package com.atguigu.chapter04
object $01_Block {
/**
* java的流程控制语句
* 1.分支判断
* if-else
* switch
* 2.循环
* for,while,do-while
* scala的流程控制
* 1.分支判断:if-else
* 2.循环:for,while,do-while
* 块表达式:由{}包裹的一段代码称之为块表达式,块表达式有结果值,结果值是{}中最后一个表达式的结果值
*
*/
def main(args:Array[String]):Unit={
val r = {
println("hello...")
val c = 10
val d = 20
val e =c+d
c+d
}
println(r)
10+20
}
}
2.if-else
package com.atguigu.chapter04
object $02_if {
/**
* java关于分支判断的用法
* 单分支: if(布尔表达式){....}
* 双分支: if(布尔表达式){....} else {....}
* 多分支: if(布尔表达式){....} else if(布尔表达式){....}.. else{..}
* scala if 语句的用法与java的完全一致
* scala中if-else语句有返回值,返回值是符合条件的分支的{}中最后一个表达式的结果值
*/
def main(args:Array[String]):Unit={
//单分支
val a = 10
if(a % 5 == 0){
println("a是5的倍数")
}
//双分支
val r = if(a%3==0){
println("a是3的倍数")
20
}else{
println("a不是3的倍数")
10
}
println(r)
//多分支
val result = if(a%4==0){
println("a是4的倍数")
100
}else if(a%3==0){
println("a是3的倍数")
200
}else{
if(a%2==0){
println("a是偶数")
300
}else{
println("a是奇数")
400
}
}
println(result)
}
}
3.for循环
package com.atguigu.chapter04
object $03_For {
/**
* ===================================
* for循环两个重要方法
* to方法:
* 语法:start.to(end) / start to end
* to方法会生成一个左右闭合的集合
* until方法
* 语法:start.until(end) / start until end
* until方法会生成一个左闭右开的集合
* ===================================
* for循环基本语法:for(变量 <- 集合/数组/表达式){....}
* ===================================
* 守卫:for(变量<- 集合/数组/表达式 if(布尔表达式)){....}
* ===================================
* 步长:for(变量<-start to/until end by step){....}
* ===================================
* 嵌套for循环:for(变量<- 集合/数组/表达式; 变量名 = 值;变量<- 集合/数组/表达式;...){....}
* ===================================
* 引入变量:for(变量<- 集合/数组/表达式; 变量名=值; 变量<- 集合/数组/表达式;...){.....}
* ==================================
* yield表达式:
* for循环默认没有返回值,如果想要for循环有返回值需要在{}之前加上yield关键字
* 语法:for(变量<- 集合/数组/表达式) yield{....}
* ==================================
*/
def main(args:Array[String]):Unit ={
//for循环基本语法
for(i<- 1 to 10){
println(s"i=${i}")
}
println("*" * 100)
//for循环结合条件判断
for(i<- 0 to 10){
println(s"i+i=${i+i}")
if(i%2==0){
println(s"i=${i}")
}
}
println("+" * 100)
//守卫
for(i<- 0 to 10 if(i%2==0)){
println(s"i=${i}")
}
//步长
for(j<- 1 to 10 by 2){
println("j=" + j)
}
println("-" * 100)
//嵌套for循环
for(i<- 1 to 10){
val k = i * i
for(j<- 1 to k){
println(s"i+j=${i+j}")
}
}
println("%" * 100)
for(i<- 1 to 10; j<- 1 to i){
println(s"i+j=${i+j}")
}
println("&" * 100)
//引入变量
for(i<- 1 to 10 ; k = i * i ; j<- 1 to k){
println(s"i+j=${i+j}")
}
//yield表达式
val result = for(i<- 1 to 10) yield{
i * i
}
println(result.toList)
}
}
4.while循环和do…while循环
package com.atguigu.chapter04
object $04_WhileAndDoWhile {
/**
* scala while与do-while用法与java完全一样
* while循环是先判断后执行
* do-while是先执行后判断
*/
def main(args:Array[String]): Unit ={
//while
var a = 11
while(a<=10){
println(s"a=${a}")
a=a+1
}
//do-while
var b = 11
do{
println(s"b=${b}")
b=b+1
}while(b<=10)
}
}
5.break and continue
package com.atguigu.chapter04
import scala.util.control.Breaks.{break, breakable}
object $05_BreakAndContinue {
/**
* break:结束整个循环
* continue:结束本次循环开始下一次循环
*
* scala没有break和continue
* scala实现break/continue
* 1.导包:import scala.util.control.Breaks._
* 2.使用breakable与break方法实现
*/
def main(args: Array[String]): Unit = {
var a =0
//break
/*try {
while (a <= 10) {
if (a == 5) {
throw new Exception("...")
} else {
println(s"a=${a}")
a = a + 1
}
}
} catch {
case e:Exception=>
}*/
//continue
/*while (a<=10){
try {
if (a == 5) {
a = a + 1
throw new Exception
} else {
println(s"a=${a}")
a = a + 1
}
} catch {
case e:Exception =>
}
}*/
//scala实现break
breakable({
while(a<=10){
if(a==5){
break()
}else{
println(s"a=${a}")
a=a+1
}
}
})
//scala实现continue
var b = 0
while (b<=10){
breakable({
if(b==5){
b=b+1
break()
}else{
println(s"b=${b}")
b=b+1
}
})
}
}
}