大数据学习day14-----第三阶段-----scala02------1. 元组 2.类、对象、继承、特质 3.函数(必须掌握)
1. 元组
映射是K/V对偶的集合,对偶是元组的最简单的形式,元组可以装着多个不同类型的值
1.1 特点
元组相当于一个特殊的数组,其长度和内容都可变,并且数组中可以装任何类型的数据,其主要用处就是存一些类型不同的数据,如定义一个方法,其要返回多个类型不同的值,如果在java中就需要定义一个bean去set这些值并返回,而scala就方便了,直接将不同类型的数据放入元组返回。
1.2 创建元组
定义元组时用小括号将多个元素包起来,元素之间用逗号分隔,元素的类型可以不一样,元素的个数可以任意多个,如
object TupleDemo { def main(args: Array[String]): Unit = { val tuple: (Int, Double, String) = m(1, 2.5) } def m(x: Int, y: Double) = { val x1 = x*10 val y1 = y*100 val w1 = "hello" (x1, y1, w1) } }
此处涉及的快捷键:当定义元组时(m(1, 2.5)),这个时候在后面写上.var,回车即可得到变量,此时会出如下选择框(看是否给元组加类型),如下:
alt+t即可选中Specify type(给元组加上类型),变量等定义也是一样的,当元组已经定义完了,并且没有加上数据类型,但后面又想加上,此时的快捷键为alt+enter
1.3 获取元组中的值
获取元组中的元素可以使用下划线加角标,但是需要注意的是元组中的元素角标是从1开始的,此外还可以自己将元组中的元素赋值给某个数(如下,a,b分别代表feng,1314)
1.4 将对偶的集合(元组不行)转换成映射
1.5 拉链操作
zip命令可以将多个值绑定在一起
注意:如果两个数组的元素个数不一致,拉链操作后生成的数组的长度为较小的那个数组的元素个数
2. 类、对象、继承、特质
2.1 类
Scala的类与java类比起来更加简单,与python中类似
2.1.1类的定义
在scala中,类并不用声明为public,默认就是public,并且在一个Scala源文件中可以包含多个类,所有这些类都具有公有可见性
class Student { //用val修饰的变量是只读属性,有getter但没有setter //(相当与Java中用final修饰的变量) val id = 666 //用var修饰的变量既有getter又有setter,下划线代表对应类型的默认值,必须指定变量的类型 var age: Int = _ //类私有字段,只能在类的内部使用,和伴生对象中使用 private var name: String = "tom" //对象私有字段,访问权限更加严格的,只能在类的内部【当前实例中使用】 private[this] val pet = "小强" }
//private 和 private[this]同样可以修饰方法 //类和伴生对象中的属性和方法都可以用访问权限控制符修饰 //类和伴生对象可以相互访问private修饰的变量和方法 //private[this]如果在类中定义,就只能在类的内容使用 //private[this]如果在object中定义,就只能在object的内容使用
2.1.2 构造器
(1)主构造器
每个类都有主构造器,主构造器的参数直接放置在类名后面,与类交织在一起,主构造器会执行类中定义的所有语句(new构造器所在的类即会执行)
案例
//主构造器
class Person(var name: String, var age: Int) { println("执行主构造器") println(name+","+age) print("主构造器执行完") } object Person { def main(args: Array[String]): Unit = { val person: Person = new Person("隔壁老王",38) } }
执行结果
可见,在伴生对象中,new完Person对象后,Person类中的代码就被执行了
(2)辅助构造器
- 辅助构造器是对主构造器的补充和扩展,辅助构造器的第一行一定要调用主构造器或者是其他已经调用了主构造器的辅助构造器
//主构造器 class People(val name: String) { var age: Int = _ var gender: String = _ //辅助构造器,是对主构造器的补充和扩展 def this(name: String, age: Int) { //辅助构造器的第一行一定要调用主构造器 this(name) this.age = age } def this(name: String, age: Int, gender: String) { //辅助构造器的第一行一定要调用主构造器,或者是其他的辅助构造器 //this(name) this(name, age) this.gender = gender } }
注意:由于辅助构造器是对主构造器的扩展,所以主构造器的参数一般比辅助构造器的参数少
- 如果定义主构造器,参数没有用var或val修饰,那么就不会成为这个类的成员变量======>局部变量(见零基础学习java day07)
(3)构造器的私有化
在类名后加private就变成了私有的构造器,其只能在其伴生对象中使用
2.2 对象
2.2.1 单例对象(可参考零基础学习java day08)
在scala中,小写的object代表的是一个静态对象,也是单例对象,当满足一定条件时(和某个类名相同,就是该类的伴生对象)就是伴生对象
运行结果
可见,s1和s2是同一个实例
2.2.2 伴生对象
在Scala的类中,与类名相同并且被object修饰的对象叫做伴生对象,类和伴生对象之间可以相互访问私有的方法和属性
2.2.3 Apply方法
通常我们会在类的伴生对象中定义apply方法,当遇上伴生对象(参数1.....参数n) 时,apply方法会被调用
object ApplyDemo { def apply(): Unit = { println(888) } def apply(x: Int): Unit = { println(x) } def apply(x: Int, y: Double): Unit = { println(x + y) } def main(args: Array[String]): Unit = { //静态对象名后面跟(),就是调用对应的apply方法 //ApplyDemo() //ApplyDemo.apply() ApplyDemo(666) ApplyDemo(6, 7.5) ApplyDemo.apply(6, 7.5) val arr = Array(1, 2, 3, 4, 5) } }
伴生对象() ==伴生对象.apply()
2.3 继承
- Scala中继承使用extends,实现接口使用with
- 在scala中,第一次不论是继承还是实现特质,都使用extends关键字,并且extends只能用一次
多态的两个前提:父类引用指向子类;重写相应的方法
3 函数
在Scala中,方法就是方法(method),函数就是函数(function),函数本质上是一个引用
(1) 函数的定义形式
一定要调用这个函数,否则不会执行,此处的f(2)相当于f.apply(2)
(2)函数的完整定义(加上函数的类型)
(3)匿名函数
scala中的匿名函数即不需要引用,以下便是一个匿名函数
(4)单词统计例子
- 求集合中的偶数
第一种方法(非函数式编程):
第二种方法(函数式编程)
首先定义一个函数,在将这个函数作为参数传入Scala自带的高级函数(此处是filter)中,即可得到结果
- 统计集合中单词的个数(即line中单词的个数)
a. 首先需要将单词切割,得到如下结果
更加简洁的写法
b 进行统计单词的个数
可以将上面4不组合成一步,就可以一行代码解决问题
在IDEA上写词案例: