一、重温
1、函数的定义
def function_name(a:String,b Int):String【返回值类型】 = {
//方法体
//最后一行是整个函数的返回值
}
2、to until Range的区别
to:[]
until:[)
Range:[)
3、for
4、默认参数/命名参数/变长参数(:_*)
5、面向对象编程
class
new
object
构造器:主/附属构造器
继承
重写:方法/属性 override
抽象类
二、object&class
1、object
创建object类Timer
/* 计数器 (1)object 修饰的类不需要new就可以直接使用 (2)静态类 (3)可以用类名.方法名直接调用 */ object Timer { var count = 0 def currentCount: Long ={ count += 1 count } def main(args: Array[String]): Unit = { println(Timer.currentCount) println(Timer.currentCount) println(Timer.currentCount) } }
总结:
(1)object 修饰的类不需要new就可以直接使用 (2)静态类(静态的东西都写在object里) (3)可以用类名.方法名直接调用
2、class
同名:“伴生”
称为:object是class的伴生对象,class是object的伴生类
3、类中方法的调用
object ApplyDemo { println("ApplyAPP object enter") var count = 0 def incr = { count += 1 } def static(): Unit ={ println("this is a static function...") } println("ApplyAPP object leave") } object ApplyAppTet{ def main(args: Array[String]): Unit = { ApplyDemo.static() } }
总结:
1)调用了静态类中其中一个方法,会从静态类的入口进去,从头到尾顺序执行”打印“”输出“,最后执行静态类调用的方法。期间函数不执行。
2)object直接调用function,类似于Java里面调用static的方法一样
4、class里面的方法需要new一个对象才可以调用
package day03 class ApplyDemo{ def ApplyClassTest(): Unit ={ println("this is classTest") } } object ApplyDemo { println("ApplyAPP object enter") var count = 0 def incr = { count += 1 } def static(): Unit ={ println("this is a static function...") } println("ApplyAPP object leave") } object ApplyAppTet{ def main(args: Array[String]): Unit = { ApplyDemo.static() // for (i <- 0 to 10){ // ApplyDemo.incr // } // println(ApplyDemo.count) val a = new ApplyDemo println(a) } }
而最后一行写入
println(a.ApplyClassTest())
可以成功调用class里面的方法了。
总结:
1)与object直接可以调用类里方法不一样。class需要new一个
2)也是顺序调用,先进入object,最后才到class方法里
5、拓展
(1)ApplyApp()
==> 以后看到伴生()没有new的,其实底层调用的就是伴生Object里面的apply方法
(2)println(b())
把apply()方法放到class类里面
总结:
class和object都可以定义apply方式
Object() ==> Object里面的apply-------------------->不用new一个对象出来就可以调用
val a = new ClassA() a() ==> Class里面的apply方法----------------------->要new对象出来调用
三、数组
1、定长:Array
(1)定义
val a = new Array[String](5)
(2)长度
(3)取值
a(0)
a
(4)工作中常用定义数组的方式
val b = Array("aaa","bbb","ccc")
必然是调用了Object中的apply方法,在apply方式中new了一次
(5)数组下标从0开始
(6)修改
(7)数组的运算
.sum/.max/.min
(8)数组转字符串
.mkString
c.mkString:
默认直接转成字符串
c.mkString(start:String,sep:String,end:String):
第一个参数:拼接字符串左边的值;第二个参数:分隔符;第三个参数:拼接字符串右边的值
c.mkString(sep:String):
分隔符
2、变长:ArrayBuffer
(1)定义
import scala.collection.mutable.ArrayBuffer
val c = ArrayBuffer[Int]()
(2)赋值
c += 1
(3)变长+定长采用++=
(4)自定义位置赋值
.insert
第0的位置赋值0,之前的值往后移。
(5)删除值
.remove()
(6)删除多个值
.remover(第n个位置,删除n个)
(7)从最后往前删除值
(8)变长转换成定长
.toArray
(10)遍历
for循环
val c = ArrayBuffer[Int]() c += 1 c += 2 c += 3 for (i <- 0 until(c.length)){ println(c(i)) }
for循环增强版
val c = ArrayBuffer[Int]() c += 1 c += 2 c += 3 for (ele <- c){ println(ele) }
四、caseClassApp
1、可以不用new就直接使用
object CaseClassApp { def main(args: Array[String]): Unit = { println(Dog("ruoze数据-巨人的狗")) } } //case class是不用new就可以直接使用 case class Dog(name:String)
2、模式匹配(后面讲)
五、trait
1、源码分析
sparkcontext里面的logging
2、一个类实现trait的方法,需要使用关键字with,第一个使用extends,后续都是用with
raitApp实现了两个接口,第一个是logging,第二个是Serializable,所以后面用with连接
object traitApp extends Logging with Serializable with RuoZeTrait { }
六、List
1、Nil(实际是空的list)
(1)类型
2、List的定义(定长)
object ListApp { def main(args: Array[String]): Unit = { val l = List(1,2,3,4) } }
点进去看源码:
没有new就可以用,因此是重写了apply方法,将数组转换成List
3、.head和tail
head拿的是List的第一个元素
tail返回的是去掉head之外的List
List = head + tail
4、变长List
ListBuffer
import scala.collection.mutable.ListBuffer
5、变长List的一些操作
5、拓展
6、Set
Set Vs List
set:无序、不重复
list:有序,可重复
7、extends App
好处:不需要写main方法了
package day03 object MapApp extends App { println("ruoze") }
一般不建议使用
七、Map
1、定义
2、取值
a("key")
3、修改
不可改,工作中很少使用不可改的Map
4、可变Map的定义
import scala.collection.mutable.HashMap
5、可变Map赋值
c("key")=value
可修改了
6、工作中如何使用Map
c.get("ruoze")
如果key没有,就是None
如果key有,就是Some(value)
工作中常用c.getOrElse:获取不到key的时候,赋予默认值
总结:
这样工作上对找不到的数据可以很方便的进行区分操作,否则处理Null很麻烦。
7、添加好几个键值对
8、遍历
方法一:
for ((key,value) <- c){ println(key + ":" + value) }
方法二:
for (ele <- c.keySet){ println(ele + ":" + c(ele)) } }
方法三:
for ((key,_) <- c){ println(key + ":" + c.getOrElse(key,-99)) }