1 scala简介
- 面向对象和面向函数
- 静态类型提高效率
- 运行在JVM和JS上
特点
- 优雅 简洁
- 速度快
- 兼容HADOOP生态
- spark是scala编写的
- 函数式编程有利于数据流式处理
2 scala环境搭建
2.1 环境变量配置
下载
windows环境
解压 --系统--高级设置--系统环境变量 配置SCALA_HOME
linux环境
解压 配置 /etc/profile
2.2 IDEA搭建scala项目
2.2.1 安装scala插件
retstart 重启IDEA
2.2.2 new project
// 1 object中的所有的内容默认是static
object Demo1 {// 等同于java的main方法 程序的入口def main(args: Array[String]): Unit = {// 打印数据 简洁println("hello scala")}
}
在scala中有class和object两种
object中的内容默认是static修饰的 , 静态的 ,所以main方法写在object中才能执行
3 数据类型
Any 类似于java中的Object 所有类的父类
Any AnyVal 数值
AnyRef 引用类有关 : 1 java的所有的类 2 scala的任意类 (scala类和集合类工具类)
在scala中所有的类型都是对象(int i--->i:Int) i 的父类也是Any
Null 是所有的ValRef的子类
Nothing是所有类的子类 : 异常
3.1 数值类型
val name:String = "zss"
val name2 = "ls"
val id:Long=1232
var age = 21
package com._51doit.day01.demo/*** FileName: Demo3* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description: 变量* 1 定义* 2 取值 打印*/
object Demo3 {def main(args: Array[String]): Unit = {///**//*** 1 数据类型自动的推导* 2 声明数据类型* 3 代码的行末可以不写 不建议写 ;* 4 scala是一种强数据类型的编程语言 变量一旦声明数据类型是确定的不可再变 (数据类型转换)* name=12 错误的*/var name = "zss" // 数据类型自动的推导var nickname:String = "" // 声明数据类型name="lss" // 再赋值// name.prt name.sout 快速返回打印println(name)/*** 变量定义* val value 值* var variable*/val id = "abc" // 使用val修饰的遍历不能再修改值 常量/*** 总结* 1 在scala中修饰变量的两个关键字 是 val 和 var* 2 val 常量 不能变化* 3 var 可以再赋值* 4 建议使用val声明变量* 5 变量定义的时候要赋值* 静态类型*/// val age:Int = 0// 变量的取值 s"$name"println(id)print(name)//println(name+"--"+id+"--"+nickname)println()println("$name,$id")println(s"$name-$id")//lss,abcprintln(s"$name")printf("" +"" +"" +"" +"" +"" +"" +"")}}
3.2 数据类型转换
1 在scala中有toXXX方法 进行类型转换的 2 v2.isInstanceOf[StringOps] 3 asInstanceOf[P] 强制类型转换 要有继承关系 有类型转换的需求使用toXX 没有对应的方法 使用 asInstanceOf[DataType]
package com._51doit.day01.demoimport scala.collection.immutable.StringOps/*** FileName: DataConv* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description:* 1 在scala中有toXXX方法 进行类型转换的* 2 v2.isInstanceOf[StringOps]* 3 asInstanceOf[P] 强制类型转换 要有继承关系* 有类型转换的需求使用toXX 没有对应的方法 使用 asInstanceOf[DataType]*/
object DataConv {def main(args: Array[String]): Unit = {val v1 = "123"val v2 = 22/*** 1 在scala中有toXXX方法 进行类型转换的* toInt* toDouble* toFloat...*/println(v1.toInt+v2)// 2 判断是否是某种数据类型val b: Boolean = v2.isInstanceOf[StringOps]println(b)// 3 asInstanceOf[P] 强制类型转换 要有继承关系val b1 = new B()val a1 = new A()// b1.asInstanceOf[A] 可以向上转型 强制类型转换/*** ClassCastException: com._51doit.day01.demo.A cannot be cast to com._51doit.day01.demo.B*/a1.asInstanceOf[B]}}
自定义两个类
/*** FileName: B* Author: 多易教育-DOIT* Date: 2020/10/30 0030 * Description: */
class B extends A{
}/*** FileName: A* Author: 多易教育-DOIT* Date: 2020/10/30 0030 * Description: */
class A {}
4 流程控制
4.1 if 语法
1 语法:
if() {} else {}
if() {} else if (){} ...else{}
if(){
if(){}else{}
}
2 数组的定义
3 数组的取值
4 Random类的基本使用使用
package com._51doit.day01.demo.i_fimport java.util.Random/*** FileName: IfDemo1* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description:* 在scala中有流程控制语句* if() else if() else if() else* if(){* if(){* if(){}else {}* }* }* for* while*/
object IfDemo1 {def main(args: Array[String]): Unit = {// 定义个数组val arr = Array[String]("java", "js", "sql", "scala")//数组的取值 arr(index) 0开始计数// println(arr(1))// 随机获取一个数组的元素val random = new Random()// 生成一个随机数据 不会超过参数val i: Int = random.nextInt(arr.length)val sub = arr(i)println(sub)// 判断元素的值 根据值做判断if (sub == "java") {println("java基础")} else if (sub == "js") {println("javascript")} else if (sub == "sql") {println("结构化查询语言")} else {println("高级语言")}}}
package com._51doit.day01.demo.i_fimport scala.util.Random/*** FileName: IfDemo2* Author: 多易教育-DOIT* Date: 2020/10/30 0030 * Description: */
object IfDemo2 {def main(args: Array[String]): Unit = {// 定义数组val arr: Array[String] = Array("java", "js", "sql", "scala")// val arr2: Array[Int] = Array(1, 2, 3, 4) 自动类型推导// 取值println(arr(1))// 随机数据val random = new Random()val i: Int = random.nextInt(arr.length)val element: String = arr(i)println(element)// 判断if(element.startsWith("j")){println("以j开头")if(element.endsWith("a")){println("java基础")}else{println("javascript")}}else{println("不以j开头")if(element.length==3){println("结构化查询语言")}else{println("高级编程语言scala")}}}
}
4.2 代码块的返回值
package com._51doit.day01.demo.i_f/*** FileName: BlockDemo* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description: */
object BlockDemo {def main(args: Array[String]): Unit = {/*** 1 代码块的最后一行内容作为代码块的返回值* 2 if的返回值是 执行分支的最后一行内容* 3 返回值类型设计各个分支的最后一行内容的父类型* 4 最后一行是 打印语句 返回的内容是 () : 没有返回内容*/val res = {"hello"1212.3"abc"}println(res)val res2:Any = if ("a" != "a") {"a"} else if ("a" == "b") {13.2} else {12println(" ")}println(res2)}}
4.3 for循环
循环的基本语法 fro(e <- 表达式|集合|数组)
1 to 10 [1,10]
1until 10 [1,10)
package com._51doit.day01.demo.f_o_r/*** FileName: ForDemo* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description:* for(i <- 1 to 10 ){}* for(i <- 1 until 10) {}* for(e <- arr){}*/
object ForDemo {def main(args: Array[String]): Unit = {// 遍历数组val arr = Array("tom" , "jim" , "cat" , "jerry" ,"jack" , "ross")for(i <- 1 to 10){// 1 10// println(i)}//增强循环 将集合中的每个元素 依次赋值给 i变量val range = 1 to 10for(i <- range){// [1 10]// println(i)}for(i <- 1 until 10){ // [1,10)// println(i)}// 1 依次获取数组中的每个元素 赋值给e变量for (e <- arr){// println(e)}// 2 使用角标的形式for(index <- 0 to arr.length-1){println(arr(index))}for(i <- 0 until arr.length){println(arr(i))}}
}
守卫模式 for(i <- if )
package com._51doit.day01.demo.f_o_r/*** FileName: ForDemo2* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description: 守卫模式* 1 简洁 减少循环次数* 2 在scala中没有* break 结束循环* continue 跳出当次循环*/
object ForDemo2 {def main(args: Array[String]): Unit = {/* for(i<- 1 to 10 if i%2==0){ // 单个条件守卫模式println(i)}*/for(i<- 1 to 10 if i%2==0 && i>5){ // 多条件的守卫模式 &&println(i)}/* for(i <- 1 to 10 ){if(i%2!=0){println(i)}}*/}}
流程控制
break 结束循环
continue 跳出当次循环return 跳出方法
package com._51doit.day01.demo.f_o_r
import scala.util.control.Breaks._
/*** FileName: ForDemo3* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description: 控制循环* 在scala中没有* break 结束循环* continue 跳出当次循环*/
object ForDemo3 {def main(args: Array[String]): Unit = {/* for(i <- 1 to 10){println(s"hello ${i}")if(i==5){return}}*/// 使用守卫模式实现停止当前循环var flag = truefor (i <- 1 to 10 if flag) {println(s"hello ${i}")if(i==5) flag=false}}
}
continue
package com._51doit.day01.demo.f_o_r/*** FileName: ForDemo4* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description: */
object ForDemo4 {def main(args: Array[String]): Unit = {// val arr = Array("a","b","c" ,"f")// arr.foreach(e=>println(e))// arr.foreach(e=>println(e.toUpperCase.equals("A")))/* arr.foreach(e=>{val str: String = e.toUpperCase()if(str.equals("A")){println(str)}})*/import scala.util.control.Breaks._val arr = Array(1,2,3,4,5,6,7,8)arr.foreach(e=>{breakable(if(e!=5 && e!=6 && e!=2){println(e)})})}
}
推导式
/*** FileName: ForDemo5* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description:* 推导式 yield 处理* 获取符合条件的每个元素 处理以后 放在新的集合中*/
object ForDemo5 {def main(args: Array[String]): Unit = {val arr = Array(1,2,3,4,5,6,7,8,9)// 推导式val res: Array[Int] = for (e <- arr if e > 4) yield e*10res.foreach(e=>println(e))}
}
将成绩及格的同学过滤出来放在新的数组中
/*** FileName: Student* Author: 多易教育-DOIT* Date: 2020/10/30 0030 * Description: 样例类* 作为以前的pojo类使用* Student 类似于java中的javabean* 有getset方法* 重写toString* 重写equals hashcode*/
case class Student(sid:Int , name:String , score:Double)
package com._51doit.day01.demo.f_o_rimport com._51doit.day01.demo.pojo.Student/*** FileName: Demo* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description:* * 学生成绩类 数组* * 1 学生类 放在学生成绩数组* * 2 放在数组中 遍历 守卫模式获取及格的人 推导式放入新的数组*/
object Demo {def main(args: Array[String]): Unit = {val stus = Array[Student] (Student(1,"jim",88),Student(2,"tom",66),Student(3,"班长",99) ,Student(4,"rose",58))// 遍历数组中的每个学生 守卫模式 判断学生成绩大于60 符合条件 推导式 收集符合条件的学生放入新的数组中// val names: Array[String] = for (stu <- stus if stu.score > 60) yield stu.name.toUpperCaseval res: Array[Student] = for (stu <- stus if stu.score > 60) yield stu//res.foreach(println(_))res.foreach(println(_))}}
嵌套循环
/*** FileName: ForDemo6* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description: 嵌套循环 */
object ForDemo6 {def main(args: Array[String]): Unit = {/* for(i <- 1 to 9 ; j<-1 to 3){println(s"$i $j")}*/for(i <- 1 to 9 ; j <- 1 to i){print(s"$j * $i ="+(i*j)+"\t")if(i==j){println()}}}
}
5 数组的遍历
for(e <- arr)
for(i <- 0 to|until arr.length[-1])
arr.forEach
arr.map
/*** FileName: ArrayEach* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description: */
object ArrayEach {def main(args: Array[String]): Unit = {val arr = Array("tom", "jim", "peiqi", "乔治", "nimou")// 1 遍历 arr.for 回车for (elem <- arr) {}// 2 角标for (i <- 0 to arr.length - 1) {arr(i)}//3 角标for (i <- 0 until arr.length) {arr(i)}// 4 forEach 方法是没有返回值 常用于集合打印// arr.foreach(e=>println(e)) // e=>e _// arr.foreach(println(_))// arr.foreach(println) // 默认打印每个元素//arr.foreach(e=>println(e.toUpperCase))// 打印数据// arr.foreach(e=>print(e+" "))// 处理数据var res = ""arr.foreach(e => { // =>后面的代码是每个元素执行一次res += e + " "})// println(res.trim)// 5 map方法 方法是可以有返回值 对集合中的每个元素进行操作// arr.map(println)// arr.map(println(_))// arr.map(e=>println(e))//val res2: Array[String] = arr.map(_.toUpperCase)/*val res3: Array[Any] = arr.map(e=>{if(e.startsWith("j")){e.toUpperCase}})*//*** _ 代表每个元素*/arr.foreach(println)arr.foreach(println(_))arr.map(_.toUpperCase)arr.map(e => println(e))}}
5 方法和函数
什么是方法:是一段逻辑代码的封装 完成处理数据的任务
返回值 方法名(参数类型)
函数 : 和方法的功能一样 是一段逻辑代码的封装 完成处理数据的任务 调用重复使用
函数比方法更高级.可以单独存在 ,理解成特殊的变量 函数可以作为参数或者返回值的
5.1 方法的定义
package com._51doit.day01.demo.f_m/*** FileName: Demo1* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description: */
object Demo1 {def maxValue(a:Double , b:Double ,c:Double) ={var max:Double = 0if (a>b && a>c){max = a}else if(b>c){max = b}else{max =c}max}/*** 定义一个方法* 处理的数据* 返回的数据* 怎么处理* 关键字 def 定义方法* add 方法名* (x:Int , y:Int , z:Int) 方法的参数类型列表* {x+y+z} 方法体* Unit 是没有返回值的方法 void*/def add(x:Int , y:Int , z:Int)={println(x+y+z)}/*** 没有参数的方法 ()* 调用的时候可以写() 可以不写*/def show(): Unit ={println("I show my face!!")}/*** 没有参数的方法 ()可以省略 调用的时候省略()*/def show2(): Unit ={println("I show your face!!")}def main(args: Array[String]): Unit = {add(1,2,6)val max = maxValue(100,34,67)println(max)show()show2()}
}
package com._51doit.day01.demo.f_m/*** FileName: Demo2* Author: 多易教育-DOIT* Date: 2020/10/30 0030 * Description: */
class Demo2 {/****/def muti(x:Int,y:Int) ={x*y}}
package com._51doit.day01.demo.f_m/*** FileName: Test1* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description:* 方法的定义* def 方法名(参数列表):返回值={方法体}* 方法的调用* 1 如果方法在object中 静态方法 直接 Demo1.方法名(实参)* 2 如果方法在class中 普通方法 new Demo2().方法(实参)*/
object Test1 {def main(args: Array[String]): Unit = {Demo1.show2()val res: Int = new Demo2().muti(3, 2)println(res)}}
5.2 函数的定义
package com._51doit.day01.demo.f_m/*** FileName: Demo3* Author: 多易教育-DOIT* Date: 2020/10/30 0030* Description: 函数的定义和调用* 函数 : 功能和方法一样*接收数据 返回结果处理数据* () =>{}* 要处理的数据类型 => {怎么处理}*/
object Demo3 {/*** 定义一个函数 将两个字符串转大写以后拼接*/val f1 = (str1:String, str2:String)=>{(str1+str2).toUpperCase //代码块的最后一行是函数的返回值}/* def m(str1:String, str2:String)={(str1+str2).toUpperCase}*/val f2 = (x:Long, y:Long)=>{x+y}def main(args: Array[String]): Unit = {val res: String = f1("abc", "efg")println(res)}}