大数据|Scala语言入门


Scala入门

      • 一.Scala安装
      • 二.类和对象
        • 1.Scala基本数据类型
        • 2.Scala定义类
        • 3.Scala单例对象
        • 3.重载构造
        • 4.类的继承
        • 5.伴生对象
      • 三.简单语法
        • 1.if-else
        • 2.循环
        • 3.方法
        • 4.字符串
        • 5.数组
        • 6.集合
      • 四.常用语法
        • 1.Trait
        • 2.Match
        • 3.样例类
        • 4.隐式值与隐式参数
        • 5.隐式转换函数
        • 6.隐式类

一.Scala安装
https://www.runoob.com/scala/scala-install.html
IDEA创建Scala项目
大数据|Scala语言入门
文章图片

大数据|Scala语言入门
文章图片

二.类和对象
1.Scala基本数据类型 基本与java类似,但首字符要大写
类型 说明
Byte -128-127
Short -32768-32767
Int -2147483648-2147483647
Long 64位
Float 32位单精度浮点数
Double 64位双精度浮点数
Char 16位无符号Unicode字符
Boolean true或者false
Unit 等同void
Null null或者空引用
Nothing 类的最底层
String 字符序列
Any 所有类的超类
Scala使用关键词 "var" 声明变量,使用关键词 "val" 声明常量,可以省略类型,会自动检测类型
val name = "song"; // 常量 var age = 18// 变量 var num:Int = 10 // 变量

2.Scala定义类 属性定义:类的括号里可以定义参数,但必须指明类型,格式参数名:类型,可以看到,类似于java的有参构造函数,有了参数就有了构造,默认有set和get方法,只有var变量可以set
方法声明:def functionName ([参数列表]) : [return type]
class Person(xname:String,xage:Int){// 类 val name = xname; val age = xage; def sayName(): Unit ={ // 方法 println("My name is - " + Lesson_ClassAndObj.name) } }

3.Scala单例对象 在 Scala 中,是没有 static 这个关键字,但是它也为我们提供了单例模式的实现方法,那就是使用关键字object,object相当于java的单例,定义全是静态的
object Lesson_ClassAndObj { val name = "static test"// 等同于java中用static声明的属性def main(args: Array[String]): Unit = {// 主函数 val person = new Person("song", 24) // 对象 println(person.name); // get方法 println(person.age); // 如果age是var类型person.age = 18相当于调用set方法 person.sayName() // 调用方法 } }

大数据|Scala语言入门
文章图片

3.重载构造
  • 新构造的属性要先在类中声明
  • 新构造的第一行必须调用默认的构造
  • def this(…){…}
class Person(xname:String,xage:Int){// 类 val name = xname; val age = xage; var gender = 'N'; // 也可以var gender : String = __表示占位符def sayName(): Unit ={ // 方法 println("My name is - " + Lesson_ClassAndObj.name); }def this(xname:String,xage:Int,xgender:Char){// 重载构造 this(xname,xage); this.gender = xgender; } }

bject Lesson_ClassAndObj { val name = "static test"def main(args: Array[String]): Unit = {// 主函数 val person = new Person("song", 24) // 对象 println(person.name); // get方法 println(person.age); person.sayName() // 调用方法val person1 = new Person("kun", 28, 'M'); // 重载构造创建的对象 println(person1.gender); } }

大数据|Scala语言入门
文章图片

4.类的继承 override val xc 为重写了父类的字段
继承会继承父类的所有属性和方法,Scala 只允许继承一个父类
var不可以继承
class Person(xname:String,xage:Int){// 类 val name = xname; val age = xage; var gender = 'N'; def sayName(): Unit ={ // 方法 println("My name is - " + Lesson_ClassAndObj.name); }def this(xname:String,xage:Int,xgender:Char){// 重载构造 this(xname,xage); this.gender = xgender; }}class Person2(override val name:String, override val age:Int, val xaddress :String) extends Person(name,age){ var address = xaddress; def sayAll():Unit = { print("name - "+ name+"- age - "+age+"- address - "+address); } }object Lesson_ClassAndObj { val name = "static test"def main(args: Array[String]): Unit = {// 主函数 val person = new Person("song", 24) // 对象 println(person.name); // get方法 println(person.age); person.sayName() // 调用方法val person1 = new Person("kun", 28, 'M'); println(person1.gender); val person2 = new Person2("zhang", 16, "guangzhou") // 继承的类 person2.sayName() // 调用父类的方法 println(person2.sayAll()) } }

大数据|Scala语言入门
文章图片

5.伴生对象 当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象:companion object。你必须在同一个源文件里定义类和它的伴生对象。类被称为是这个单例对象的伴生类:companion class。类和它的伴生对象可以互相访问其私有成员
默认伴生对象是没有构造参数的,但是我们可以重写apply()方法,当调用有参构造半生对象时,会自动匹配apply()方法
// 私有构造方法 class CompanionTest private(val color:String) {println("创建" + this)override def toString(): String = "颜色标记:"+ color }// 伴生对象,与类名字相同,可以访问类的私有属性和方法 object CompanionTest{private val markers: Map[String, CompanionTest] = Map( "red" -> new CompanionTest("red"), "blue" -> new CompanionTest("blue"), "green" -> new CompanionTest("green") )def apply(color:String) = { if(markers.contains(color)) markers(color) else null }def getMarker(color:String) = { if(markers.contains(color)) markers(color) else null } def main(args: Array[String]) { println(CompanionTest("red"))//CompanionTest无参数构造,会匹配apply方法 // 单例函数调用,省略了.(点)符号 println(CompanionTest.getMarker( "blue")) } }

大数据|Scala语言入门
文章图片

三.简单语法
1.if-else
object IfElse { def main(args: Array[String]): Unit = { var x = 30; if (x == 10) { println("X 的值为 10"); } else if (x == 20) { println("X 的值为 20"); } else if (x == 30) { println("X 的值为 30"); } else { println("无法判断 X 的值"); } } }

【大数据|Scala语言入门】大数据|Scala语言入门
文章图片

2.循环
  • while 循环 运行一系列语句,如果条件为true,会重复运行,直到条件变为false
  • do…while 循环 类似 while 语句区别在于判断循环条件之前,先执行一次循环的代码块
  • for 循环 用来重复执行一系列语句直到达成特定条件达成,一般通过在每次循环完成后增加计数器的值来实现
  • break 语句 中断循环
object Circle { def main(args: Array[String]): Unit = {for(num <- 1 to 10){ // 1到10,包括10 print(num+"-"); } println()for(num <- 1 until(10,2)){// 10到9,步长为2 print(num+"-") } println()for(num <- 1 to 10 ; if(num % 2 == 0) ; if(num > 5)){ // 可以加判断条件 print(num+"-") } println()// 局部变量 var a = 1 // do 循环 do { print("Value of a: " + a +"-") a = a + 1 } while ( { a < 3 })} }

大数据|Scala语言入门
文章图片

3.方法 def functionName ([参数列表]) : [return type]
  • 如果有return,则必须指定返回值类型
  • 没有return,默认将最后一行计算的结果当做返回值
  • 传入的参数必须指定类型
object Method { def main(args: Array[String]): Unit = {def max(a:Int,b:Int):Int = { if(a > b) return a; else return b; }//def max(a:Int,b:Int):Int = { //if(a > b)a else b; //}val result : Int = max(100,20); println(result) } }

大数据|Scala语言入门
文章图片

递归方法
递归方法必须指定返回值类型
def fun(num:Int):Int = { if(num == 1) return 1 else return num * fun(num - 1) }println(fun(5))

有参数默认值的方法
def fun(a:Int=10,b:Int=20) = { a + b; } println(fun()) // 不覆盖 println(fun(100,300)) // 全部覆盖 println(fun(100)) // 覆盖a println(fun(b = 50)) // 覆盖b

大数据|Scala语言入门
文章图片

可变长参数的方法
def fun(s:String*)={ s.foreach(elem=>{println(elem)})// 两种输出方式 for(string <- s) println(string) }fun("zhang","liu","wang")

大数据|Scala语言入门
文章图片

匿名函数
=>就是匿名函数
def fun = (a:Int,b:Int)=>{ a+b }println(fun(1,6))

大数据|Scala语言入门
文章图片

嵌套
def fun(a:Int): Int ={ def fun1(b:Int): Int ={ if(b == 1) 1 else b * fun1(b - 1) } fun1(a)}println(fun(5))

大数据|Scala语言入门
文章图片

偏应用函数
def show(date:Date,log:String)={ println(s"date is $date,log is $log")// s $引用外部的属性 }def fun = show(date = new Date(),_:String) // _ 占位符 fun("a") fun("b") fun("c")

大数据|Scala语言入门
文章图片

方法参数是函数
类型指定(Int,Int) =>Int
def fun(f:(Int,Int)=>Int,s:String):String={ val res:Int = f(100,200) res + ""+s }val result = fun((a:Int,b:Int)=>{a*b},"scala") println(result)

大数据|Scala语言入门
文章图片

返回值是函数
def fun(s:String):(String,String)=>String={ def fun1(s1:String,s2:String):String={ s + s1 + s2 } fun1 }println(fun("zhang")("liu","wang"))

大数据|Scala语言入门
文章图片

方法参数和返回值都是函数
def fun(f:(Int,Int)=>Int,s:String):(String,String)=>String={ val a:Int = f(100,200) def fun1(s1:String,s2:String):String={ s1+s2+s+a.toString } fun1 }val res = fun((a:Int,b:Int)=>{a+b},"hello")("zhang","kun") println(res)

大数据|Scala语言入门
文章图片

柯里化函数
def fun(a:Int,b:Int)(c:Int,d:Int)={ a+b+c+d } println(fun(1,2)(3,4))

大数据|Scala语言入门
文章图片

4.字符串
object StringTest { def main(args: Array[String]): Unit = { val s = "zhang"// 普通字符串 val s1 = "zhang1"val sb = new StringBuffer(); // 可变字符串 sb.append(s).append("liu")println(sb)val i = s.compareTo(s1)// compareTo println(i)println(s1.charAt(1)) // 索引val chars = s.toCharArray // 字符串转数组 chars.foreach(c=>{print(c+" ")})} }

大数据|Scala语言入门
文章图片

5.数组
object ArrayTest { def main(args: Array[String]): Unit = {val array = Array[String]("ab","bc") // 直接赋值 array.foreach(s=>{print(s + " ")}) println()val array2 = new Array[Int](3) // 先声明再赋值,new不可以省略 array2(0) = 2 array2(1) = 3 array2(2) = 10 array2.foreach(num=>{print(num + " ")}) // 遍历数组 println()val array3 = new Array[Array[Int]](3) // 二维数组 三行 array3(0) = Array[Int](1,2,3,8) array3(1) = Array[Int](1,6,2) array3(2) = Array[Int](8,12,9)array3.foreach(arr=>{arr.foreach(num=>{print(num+" ")}); println()}) // 遍历二维数组var myList1 = Array(1.9, 2.9, 3.4, 3.5)// 合并数组 var myList2 = Array(8.9, 7.9, 0.4, 1.5) var myList3 =Array.concat(myList1, myList2) // 输出所有数组元素 for ( x <- myList3 ) { print( x + " ") } println()var myArr = Array.range(10,20)// 区间数组 myArr.foreach(num=>{print(num+" ")})} }

大数据|Scala语言入门
文章图片

6.集合 List
object ListTest { def main(args: Array[String]): Unit = {val list = List[String]("hello_java","zhang_kun_song") list.foreach(s=>{print(s+" ")}) // 遍历集合 println() println(list(0)) // 通过索引获取 val list3 = ListBuffer[Int]() // 可变List list3.append(1,2,3)val list1 = list.map(s => { // 对集合中的每一个元素分割,得到的是泛型为数组的集合 s.split("_")// [hello,java] [zhang,kun,song] }) list1.foreach(arr=>{arr.foreach(s=>{print(s+" ")}); println()})val list2 = list.flatMap(s => { s.split("_") // [hello] [java] [zhang] [kun] [song] }) list2.foreach(arr=>{print(arr + " ")}) } }

大数据|Scala语言入门
文章图片

Set
object SetTest { def main(args: Array[String]): Unit = { val set = Set[Int](1,2,2,2,3,4,5) val set1 = Set[Int](4,5)set.foreach((num)=>print(num+" "))// set有去重功能 println()val ints = set.intersect(set1) // 集合差集 也可以 set & set1 val ints1 = set.diff(set1) // 差集val set2 = mutable.Set[Int](1,2,3)// 可变set set2.+=(4) set2.foreach((num) =>{print(num+" ")}) } }

大数据|Scala语言入门
文章图片

Map
object MapTest { def main(args: Array[String]): Unit = { val map = Map[String,Int]("aa"->20,("b",30),("b",40)); val value = https://www.it610.com/article/map.get("aa").get // 获取value 20for(elem <- map){// 遍历map println(elem) }map.foreach(kv=>{ // 遍历集合 println(kv) })val keys = map.keys // 获取所有键值keys.foreach(key=>{// 遍历key获取value val value1 = map.get(key).get println(s"key == $key,value = https://www.it610.com/article/$value1") })val values = map.values // 获取所有valueval map1 = Map[String,Int]("aa"->20,("b",30),("c",40)); val map2 = Map[String,Int]("aa"->30,("b",40),("c",50)); val map3 = map1.++(map2)// map2替换map1 val map4 = map1.++:(map2)// map1替换map2val map5 = mutable.Map[String,Int]()// 可变map map5.put("song",24)} }

大数据|Scala语言入门
文章图片

object TupleTest { def main(args: Array[String]): Unit = { // 元组可以存不同类型的元素 val tuple = new Tuple1("zhang") val tuple2 = new Tuple2("zhang",'C') val tuple4 = new Tuple4("zhang", false, 'C', 16)val value = https://www.it610.com/article/tuple2._1 // ._xx取值 println(value)val value1 = tuple4._4 println(value1)val iterator = tuple4.productIterator// 遍历,只能先拿到迭代器 iterator.foreach(value=>{println(value)})} }

大数据|Scala语言入门
文章图片

四.常用语法
1.Trait Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大
与接口不同的是,它还可以定义属性和方法的实现
一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承
Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait
trait Audi{ val name = "Audi" def runAudi(time:Int)={ println(name+"running....."+time) } }trait Benz{ val name1 = "Benz" def runBenz(time:Int)={// 实现的方法 println(name1+"running....."+time) }def recreate():String// 未实现的方法 }class Car extends Audi with Benz {// 继承第一个用extends,第二个用with override def recreate(): String = { "recreate.." } }object TraitTest { def main(args: Array[String]): Unit = { val car = new Car car.runBenz(10) car.runAudi(20) }}

大数据|Scala语言入门
文章图片

2.Match 一个模式匹配包含了一系列备选项,每个都开始于关键字 case。每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式
case _ 什么都不匹配
可以匹配类型,也可以匹配值
object MatchTest { def main(args: Array[String]) { println(matchTest("two")) println(matchTest("test")) println(matchTest(1)) println(matchTest(6)) println("偏函数"+myTest("ooo"))} def matchTest(x: Any): Any = x match { case 1 => "one" case "two" => 2 case y :Int => "scala.Int"// 匹配Int类型 case _ => "no match" // case _ 什么都不匹配,类似 switch 中的 default }def myTest:PartialFunction[String,Int] = {// 偏函数相比match没有match了,匹配String,返回Int case "abc" => 22 case "bcd" => 66 case _ => 84 } }

大数据|Scala语言入门
文章图片

3.样例类 使用了case关键字的类定义就是样例类(case classes),样例类是种特殊的类,经过优化以用于模式匹配,默认有get和set(对val类型)方法
object CaseClass { def main(args: Array[String]) { val alice = new Person("Alice", 25) val bob = new Person("Bob", 32) val charlie = new Person("Charlie", 32)for (person <- List(alice, bob, charlie)) { person match { case Person("Alice", 25) => println("Hi Alice!") case Person("Bob", 32) => println("Hi Bob!") case Person(name, age) => println("Age: " + age + " year, name: " + name + "?") } } } // 样例类 case class Person(name: String, age: Int) }

大数据|Scala语言入门
文章图片

4.隐式值与隐式参数
  • 用implicit修饰的值就是隐式值
  • 用implicit修饰参数就是隐式参数,注意,如果方法中部分参数是隐式参数,必须使用柯里化的方式
作用
当调用方法时,不必手动传入方法中隐式参数,Scala会自动在作用域内寻找隐式值并自动传入,所以在一个作用域内不能定义多个类型一样的隐式值
object ImplicitTrans { def main(args: Array[String]): Unit = { implicit val name:String = "zhang"// implicit声明隐式值柯里化的方式def sayName(age:Int)(implicit name:String) ={// println(s"$name is student... age = $age") }sayName(10)} }

大数据|Scala语言入门
文章图片

5.隐式转换函数 作用
实现类中方法的共享
class Red{ def sayWho()={ println("Red Red Red") } }class Green{}object ImplicitTest {implicit def greenToRed(green: Green):Red = {// 隐式函数 new Red }def main(args: Array[String]): Unit = { val green = new Green green.sayWho() }}

大数据|Scala语言入门
文章图片

上面的例子中,创建了green对象,但我想用Red类中的方法,于是我就声明一个隐式函数,传入green对象,返回一个red对象,就可以调用了
注意:相同作用域内,不可以定义相同的传入参数和返回类型相同的隐式函数
6.隐式类
class Dog{} object ImplicitClass { implicit class Animall(dog: Dog){ def sayName(): Unit ={ println("dog隐式类...") } }def main(args: Array[String]): Unit = { val dog = new Dog dog.sayName// 创建了一个dog对象 } }

创建了一个dog对象,调用了sayName方法,但实际类中是没有这个方法的,于是就去找有没有一个隐式类,参数是Dog类型的,有的话就可以调用里面的方法

    推荐阅读