scala 基础 2

教程 青牛 ⋅ 于 2017-11-28 14:34:11 ⋅ 最后回复由 江南一叶 2022-07-29 13:46:59 ⋅ 9692 阅读

lazy关键字
惰性变量用法放在不可变变量之前
只有在调用惰性变量时才会去实例化这个变量,类似于java中单例模式的懒汉模式

object LazyDemo {
def init():Unit = {
 println("init")
 }
 def main(args: Array[String]): Unit = {
val property = init()       //没有lzay关键字的时候
println("init after")
println(property)
}
}
object LazyDemo2{
def init():Unit = {
println("init")
}
def main(args: Array[String]): Unit = {
 lazy val property = init()        //有lzay关键字的时候,在调用的时候才去初化它
println("init after")
println(property)
}
}

集合高级操作:

object ListDemo {
def main(args: Array[String]): Unit = {
val list0 = List(1, 2, 3, 4, 5, 6, 7, 8)
//循环每一个元素并按函数的结果生成新的集合
val list1 = list0.map(_ * 2)
//循环每一个元素并按进行过滤,过滤掉不满足条件的,返回新的集合
val list2 = list0.filter(_ % 2 == 0)
//集合升序
val list3 = list0.sorted
//集合倒序
val list4 = list3.reverse
//集合里的元素每几个分成一组
val it = list0.grouped(2)
//将迭代器转成可变数组
//val list5 = it.toBuffer
//    println(list5)
//将迭代器转成不可变序列,注意迭代器的循环在调用it.toBuffer
// 或it.toList循环到结尾所以在第一次调用的时候就把值全取出来了
val list6 = it.toList
//将list重新组合
val list7 = list6.flatten
 val list8 = List("a b c", "d e f")
 val list9 = list8.map(_.split(" "))
 //将Array[String]进重新组合,不支持元组
 val list10 = list9.flatten
//flatMap等于map和flatten的结合
val list11 = list8.flatMap(_.split(" "))
 //利用机器的空闲线程进行并行计算,也就是每个线程拿一部分数据进行并行求合,
 // 最后再进行汇总和mr的wordcount类似
val res = list0.par.sum
 //普通的求合
 val res1 = list0.sum
//按照List里从头到尾的顺序进行累加,就是从左向右加
val res2 = list0.reduce(_ + _)
 val res3 = list0.reduceLeft(_ + _)
 val res4 = list0.reduceRight(_ + _)
 //用结果演示是否并行化,分的线程不一样,结果也就不一样,因为每个线程拿到的数据都是随机的
val res5 = list0.par.reduce(_ - _)
//结定初始值为10,然后进行每一项的累加
 val res6 = list0.fold(10)(_ + _)
 val res66 = list0.fold(10)(_ - _)
//给定初始值为10,然后累加每一项,分的线程不一样,结果也就不一样
 val res7 = list0.par.fold(10)(_ + _)
//按特定顺序进行操作
 val res8 = list0.foldLeft(10)(_ + _)
 val res9 = list0.foldRight(10)(_ + _)
 val res10 = list0.foldLeft(10)(_ - _)
 val res11 = list0.foldRight(10)(_ - _)
 //因为这里par使用的是foldLeft所以是有特定顺序的
 val res12 = list0.par.foldLeft(10)(_ - _)
val list12 = List(List(1, 2), List(1, 3), List(3, 4, 5), List(2))
//    val res13 = list12.reduce(_.sum + _.sum)
//聚合操作
//    val res14 = list12.aggregate(0)((a,q) => {println(a + "," + q.sum);a + q.sum},(a ,b) => a)
 val res14 = list12.aggregate(0)(_ + _.sum, _ + _)
 val res13 = list12.foldLeft(0)(_ + _.sum)
//aggregate没有被par调用时第2个参数并没有参与运算
val res18 = list12.par.aggregate(0)((a,q) => {println(a + "," + q.sum);a + q.sum}, (a,b) => {println(a + "," + b);a + b})
println(res18)
 //并集
  val res15 = List(1,2) union List(3,4)
//交集
 val res16 = List(1,2) intersect List(1,5)
 //差集
 val res17 = List(1,2) diff List(1)
 println(res15)
println(res16)
println(res17)
}
}

wordcount


object WordCount {
def main(args: Array[String]): Unit = {
val lines = List("a b c d","a d e s","a b d e","a a a b")
 //切分并生成一个list
 val words = lines.flatMap(_.split(" "))
 //把每个单词生成 (自身,1) 的元组
val tuples = words.map((_ -> 1))
//以key(单词)进行分组
val group = tuples.groupBy(_._1)
 //统计每组key的values的长度
val mapValue = group.mapValues(_.size)
//升序
val list = mapValue.toList.sortBy(_._2)
 //降序
 val result = list.reverse
println(result)
}
}


scala中类的关键字默认就是public的,所以如果是public的则不需要加访问限制关键字
一个类文件可以声明多个类

语法:
class 类名{

}
静态类
object 类名{

}

如果类名和静态类的类名相同那这个静态类就叫做这个类的伴生对象

类中的属性:
可以分为可变(var)和不可变(val)
访问修饰可以分private和private[this]

示例:


class ClassDemo {
//用val修改的变量是只读的,相当只有get方法,没有set方法
val name: String = "hainiu"
//用var修饰的变量相当于既有get又有set方法
 var gender: String = _
//用private修饰的属性,该属性属于对象私有变量,只有本类和伴生对象能访问到
private var age: Int = _
//用private[this]修饰后,该属性属于对象私有变量,只有本类才能访问,伴生对象也访问不到,
//注意这个变量并没有指定类型这里是scala自己根据值进行推断的
private[this] val location = "北京"
}
/**
* 类ClassDemo的伴生对象
*/
object ClassDemo {
def main(args: Array[String]): Unit = {
val demo = new ClassDemo
//demo.name = "hainiu1"
println(demo.name)
println(demo.gender)
demo.gender = "男"
println(demo.gender)
println(demo.age)
//    println(demo.location)
}
}
/**
* 其它对象
*/
object ClassDemo1{
def main(args: Array[String]): Unit = {
val demo = new ClassDemo
//    demo.name = "hainiu1"
println(demo.name)
println(demo.gender)
demo.gender = "男"
println(demo.gender)
//    println(demo.age)
//    println(demo.location)
}
}

构造器:
用于对类进行属性的初始化,分为主构造器和辅助构造器

1).主构造器用法:
语法:
//参数可以有默认值
class 类名(参数列表){

}

示例:

class ConDemo(val name: String, var age: Int, location: String = "北京") {
def getLocation():String={
//不可能进行修改因为是被当成val修饰的
//    location = "上海"
//如果没有写return那最后一句代码的值就被做为返回
location
}
}
object ConDemo {
def main(args: Array[String]): Unit = {
//因为location有默认值,所以调用构造函数的时候可以不用写
val demo = new ConDemo("hainiu", 1)
//不能改因为是val修饰的
//demo.name = "hai1niu"
demo.age = 100
println(demo.name)
println(demo.age)
//不能访问因为没有val或var修饰,就相当于是用private[this] val修饰的属性,要访问只能自己写相应的get方法
//    println(demo.location)
}
}

2).辅助构造器用法:
语法:

//辅助构造器中使用的变量进行声明
var a:String = _

def this([辅助构造器参数列表...],a:String){
this(主构造器参数列表) //看自己的情况来定是否辅助构造器参数列表与主构造器参数列相同
this.a = a //这个a变量需要在class中进行声明,不然提示找不到这个变量
}

示例:

class ConDemo1(val name:String,var age:Int,location:String = "北京") {
def getLocation:String = {
location
}
var gender:String = _
/**
* 辅助构造器
*/
def this(name:String,age:Int,location:String,gender:String){
//辅助构造器第一行必须要先调用主构造器
this(name,age,location)
this.gender = gender
}
}
object ConDemo1{
def main(args: Array[String]): Unit = {
val demo = new ConDemo1("hainiu",1,"上海","男")
println(demo.name)
println(demo.age)
println(demo.getLocation)
println(demo.gender)
}
}

总结:
主构造器的参数列表要放到类名的后面,和类名放在一起,val修饰的构造参数具有不可变性,var修饰的构造参数具有可变性
如果参数没有用val或var修饰那它既不可被外面直接方问(可通过相应的get方法访问)只能在本类中使用,伴生对象也无法使用,也不可在本类中进行修改因为它被当成隐藏的val修饰的

辅助构造器可以没有,如果有要在类中进行定义,辅助构造器可以声明主构造器没有的参数,如果声明了其它参数那这个参数需要在类中进行定义,否则提示无法找到这个参数
辅助构造器也可以理解成java中的构造器重载,且辅助构造器的第一行必须要先调用主构造器(这点和python的基础调用父类比较相似)

idea使用:

file
如果按ctrl+p,提示有两行或多行的时候那就说明有铺装构造器

file
快捷键修改
单例对象
在scala中没有像java一样的static关键字
在scala中是没有静态方法和静态字段的,但是可以使用object关键字加类名的语法结构实现同样的功能
在scala中用object修饰的为单例对象,单例对象中主要存放常量和工具方法

示例:

回复帖子,然后刷新页面即可查看隐藏内容

版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海汼部落-青牛,http://hainiubl.com/topics/208
回复数量: 15
暂无评论~~
  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,可用Emoji的自动补全, 在输入的时候只需要 ":" 就可以自动提示了 :metal: :point_right: 表情列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif,教程
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
Ctrl+Enter