package cn.doit.com.day03.demo2
//跟在类名的后面,跟类交织在一起,叫主造器 主构造会执行类定义中的所有语句
// 用val和var修饰的构造器参数,会成为这个类的成员变量 默认val修饰 会成为类的成员变量
class Student(val name:String , var age:Int) {
val i = 100
//代码块
{
try {
println("hi ketty")
} catch {
case e: Exception => //可以进行try catch
} finally {}
}
def m():Unit={
println("hello world")
}
var j:Int = _ //给指定的类型的变量赋予默认值
Student.sayHi()
}
object Student {
private def sayHi(): Unit ={
println("hi tom")
}
def main(args: Array[String]): Unit = {
}
}
package cn.doit.com.day03.demo3
//在主构造器中传递的参数可以用val var修饰
class Boy(val name: String , val age: Int) {
var sal: Double = _ //对应类型变量的的默认初始值
var gender:String = _
/*
定义辅助构造器,辅助构造器一定要用def this,辅助构造器一定要调用
主构造器或其他的辅助构造器
辅助构造器的方法中的参数不用加var val修饰
构造器方法一定是this
*/
def this(name:String, age:Int, sal:Double){
this(name ,age)
this.sal = sal
}
def this(name:String ,age:Int ,sal:Double ,gender:String){
//调用了辅助构造器 相当于间接调用了主构造
this(name,age,sal)
this.gender = gender
}
}
//不用 var val修饰只是形参
class Boy2(name: String , age: Int){
}
//name weight子类可以继承 private private[this]继承不了 height只是个形参
class Boy3(val name:String , private var age:Int , private[this] val weight:Double , height:Double = 165.0){
}
object Boy {
def main(args: Array[String]): Unit = {
val b = new Boy("tom", 18, 12000.0)
println(b.sal)
}
}
package cn.doit.com.day03.demo4
/*
synchronized锁 为保证线程安全
*/
object SynchronizedDemo {
def main(args: Array[String]): Unit = {
var m: Int = 10
test(10)
test2(20)
println(m)
//为了保证线程安全,使用同步synchronized锁
def test(i: Int): Int = synchronized{
m = i + m
//赋值之后重新返回成员变量
m
}
def test2(i: Int): Int ={
println("hello girl")
synchronized{
m = i + m
m
}
}
}
}
package cn.doit.com.day03.demo4
/*
单例对象
*/
object ObjDemo {
println("hello")
println("world")
def abc(): Unit ={
println("ketty")
}
println("jerry")
abc()
}
object ObjTest {
def main(args: Array[String]): Unit = {
val obj = ObjDemo //初始化静态对象的方式一
println(obj)
//单例对象,初始化两次只会执行一次,地址值相同
val obj2 = ObjDemo
println(obj2)
//会执行两次,静态代码块类加载的时候执行一次 ,现在调用它又执行一次
ObjDemo.abc()
}
}
package cn.doit.com.day03.demo4
/*
通常我们会在类的伴生对象中定义apply方法,当遇到类名(参数一,...参数二)时,apply方法会被调用
不仅仅可以在object中定义,class中也可以定义
*/
object ApplyDemo {
def apply(): Unit = {
println("no args apply")
}
def apply(i: Int , j: Int): Unit = {
println("two int args apply")
}
/*
方法名相同 参数列表不同
方法的重载 根据调用时传入的参数区分是哪一个方法
*/
def apply(i:Int , j:Double): Unit = {
println("one int one Double args apply")
}
def main(args: Array[String]): Unit = {
// ApplyDemo.apply(1 , 2.0)
//.apply可以省略掉
ApplyDemo(1 , 2.5)
//可以 .apply 证明他是object
val arr = Array.apply(1,2,3,4,5,6)
val lst = List(1,2,3,4,5,6)
val demo = new ApplyClassDemo
//demo.apply()
//省略apply
demo()
}
}
package cn.doit.com.day03.demo4
class ApplyClassDemo {
def apply(): Unit={
println("hello world")
}
}
package cn.doit.com.day03.demo4
/*
App特质 可以不写main方法也可以运行
实际是通过反射调用了main方法
*/
object AppDemo extends App {
println("hello")
println("tom")
}
抽象类父类
package cn.doit.com.day03.demo05
//抽象类 父类
abstract class Animal {
var name:String
var age: Int
def run(): Unit
//已经实现了的方法
def breach(): Unit ={
println("呼吸氧气")
}
}
子类继承父类 实现特质
package cn.doit.com.day03.demo05
//子类继承父类 with实现接口,可以实现多个接口 中间不需要,
class Monkey extends Animal with Flyable with Fightable {
//重写抽象 (未实现的方法) 可以加override,也可以不加
override def run(): Unit = {
println("蹦蹦跳跳的跑")
}
//重写已经实现了的方法 必须加上override关键字
override def breach(): Unit = {
println("呼吸新鲜的空气")
}
//重写特质中的方法
override def fly(): Unit = {
println("坐筋斗云飞")
}
//重写了特质中以实现的方法
override def fight(): Unit = {
println("金箍棒打你")
}
override var name: String = _
override var age: Int = _
}
object Monkey {
def main(args: Array[String]): Unit = {
val monkey = new Monkey
monkey.breach()
monkey.fight()
}
}
特质
package cn.doit.com.day03.demo05
//特质 就是java8的接口
trait Flyable {
def fly(): Unit
}
特质
package cn.doit.com.day03.demo05
trait Fightable {
//已经实现了的方法
def fight(): Unit ={
println("打你")
}
}
子类
package cn.doit.com.day03.demo05
//类不论是继承还是实现接口 第一次一定使用extends关键字,之后都是使用with关键字
class Pig extends Flyable with Fightable {
//重写fly的方法
override def fly(): Unit = {
println("飞猪")
}
//重写fight的方法
override def fight(): Unit = {
println("用九齿钉耙搂你")
}
}
object Pig {
def main(args: Array[String]): Unit = {
val pig = new Pig
pig.fly()
pig.fight()
}
}
动态混入特质
package cn.doit.com.day03.demo05
class Dog {
}
object Dog {
def main(args: Array[String]): Unit = {
//动态混入特质 只有特质可以在new的时候实现特质
val dog = new Dog with Fightable with Flyable {
//在大括号中重写fight方法
override def fly(): Unit = {
println("哮天犬")
}
override def fight(): Unit ={
println("咬你")
}
}
dog.fly()
dog.fight()
}
}
多态 父类引用指向子类对象
package cn.doit.com.day03.demo05
//多态 父类引用指向子类对象
object DuoTaiDemo {
def main(args: Array[String]): Unit = {
val monkey: Animal = new Monkey
//重写后的方法
monkey.run()
monkey.breach()
}
}
package cn.doit.com.day03.cs
import java.io.{FileOutputStream, ObjectOutputStream}
import scala.beans.BeanProperty
//case可以用来模式匹配和封装案例
//也是一个特殊的class 可以创建多个实例,每个实例封装自己的数据
//可以用于模式匹配
//可以new 也可以不new 内部实现了apply方法
//默认实现序列化接口
//默认重写了toString方法
//case中的主构造器中的变量不加val var 默认就是val的 如果想重新赋值,要加上var
case class CStudent(
@BeanProperty //get set方法 可以指定@beanGetter @beanSetter
name:String , //默认val修饰 val可以省略
var age:Int
) {
//重写了toString方法 变量前面加$ , s必须要写
override def toString: String = s"String: $name , Int $age"
}
object CaseClassDemo {
def main(args: Array[String]): Unit = {
val cs = CStudent.apply("zss", 18)
println(cs.name)
println(cs.age)
val oos = new ObjectOutputStream(new FileOutputStream("D:\\a.txt"))
oos.writeObject(new User)
oos.flush()
oos.close()
}
}
package cn.doit.com.day03.cs
import scala.beans.BeanProperty
//写出到磁盘需要实现序列化接口
class User extends Serializable {
println("user constructor")
@BeanProperty
val name: String = "tom"
@BeanProperty
val age: Int = 10
}
package cn.doit.com.day04
import scala.util.Random
object CaseDemo01 extends App{
val arr = Array("YoshizawaAkiho","YuiHatano","AoiSola")
//生成随机数
val name = arr(Random.nextInt(arr.length))
println(name)
name match {
case "YoshizawaAkiho" => {
println("吉泽***老师")
}
case "YuiHatano" => println("波多***老师")
//通配" _ "
case _ => println("这不是通往幼儿园的车,我要下车")
}
}
package cn.doit.com.day04
import scala.util.Random
object CaseDemo02 extends App{
//if else方法
//val v = if(x >= 5) 1 else if(x < 2) 2.0 else "hello"
//创建一个数组传不同类型的参数
val arr: Array[Any] = Array("hello" , 1 , 2.0 , CaseDemo02)
//数组生成随机数
val v =arr(Random.nextInt(4))
//val v: Any = 2.0
println(v)
// n match case => 固定格式
v match {
//int类型的值执行x
case x: Int => {
println("Int" + x)
}
//double类型的值且 y>= 3 执行y
case y: Double if(y >= 3) => println("Double" + y)
//string类型的值执行z
case z: String => println("String" + z)
//上面条件都不满足执行 _ 通配
case _ => throw new Exception("not match exception")
}
}
package cn.doit.com.day04
object CaseDemo03 {
def main(args: Array[String]): Unit = {
//匹配数组
val arr = Array(1,3,5,6)
arr match {
//数组首位为1且长度为3 执行
case Array(1,x,y) => println(x + "" + y)
//数组中只有0 执行
case Array(0) => println("only 0")
//数组中首位为0 _*代表可变参数 执行
case Array(0,_*) => println("0 ...")
//上述都不满足 执行
case _ => println("something else")
}
//匹配集合
val lst = List(0,1,2)
lst match {
// 0 :: Nil 把0放进空的list集合中lst(0) :: 也可以写成 +: Nil代表空的List集合
case 0 :: Nil => println("only 0")
// 把 x,y放进空的list集合中 lst(x,y)
case x :: y :: Nil => println(s"x: $x , y: $y")
/*
list :+ 6 生成一个新的list,6在最后一位 并不是追加 原来的list依然存在
6 +: list 生成一个新的list,6在首位 也不是追加 原来的list依然存在
list1 ++ list2 两个list合并 list1和list2依然存在
list1 :: list2 list1作为一个元素放进list中 List(List(1,2,3),4,5,6)
*/
//把0放进去掉首位后的集合,代表首位为0
//head为首位 tail代表去掉首位以外的 返回的是集合 tails返回的是迭代器
case 0 :: tail => println("0 ...")
//上述都不满足 执行
case _ => println("something else")
}
//匹配元组
val tup = (5,3,2)
tup match {
//首位为2且长度为3 执行元组中的三个元素
case (2,x,y) => println(s"2, $x, $y")
//最后一个元素为5,且长度为3 执行中间数z的值
case (_,z,5) => println(z)
//上述都不满足 执行
case _ => println("else")
}
}
}
package cn.doit.com.day04
object WordCount {
def main(args: Array[String]): Unit = {
val lines = Array("hadoop,flink,spark,hadoop,Hive","hadoop,Flink,spark,Hadoop,spark")
val grouped = lines.flatMap(_.split(",")).groupBy(a => a.toLowerCase)
//元组中的元素特别多,容易混乱,使用模式匹配 match如果省略就要使用大括号
val a = grouped.map{
case (word , arr) => {
(word , arr.length)
}
}
println(a)
}
}
样例类 样例对象 case class Demo / case object Demo
package cn.doit.com.day04
import scala.util.Random
/*
样例类 样例对象: 专门用来模式匹配的,样例类可以创建多个实例,样例object是单例的
样例类创建实例后可以封装数据,样例object不能保存数据
样例类不需要new
*/
//样例类
case class SubmitTask(id:String , name:String)
case class HeartBeat(time:Long)
//样例对象 , 单例的 在一个JVM进程中只有一个实例
case object CheckTimeOutTask
object CaseDemo04 extends App{
val arr:Array[Product] = Array(CheckTimeOutTask , new HeartBeat(12333) , HeartBeat(5555) , SubmitTask("0001","task-0001"))
val r = arr(Random.nextInt(arr.length))
println(r)
r match {
case SubmitTask(id , name) => {
println(s"$id , $name")
}
case HeartBeat(time) => {
println(time)
}
case CheckTimeOutTask => {
println("check")
}
}
}
偏函数(PartialFunction) 专门用来做模式匹配的
package cn.doit.com.day04
object PartialFuncDemo {
//PartialFunction类型的方法就叫做偏函数
// String代表输入的类型 Int代表返回的类型
def func1: PartialFunction[String , Int] ={
case "one" => 1
case "two" => 2
case _ => -1
}
//不用偏函数也可以实现
def func2(num: String): Int = num match {
case "one" => 1
case "two" => 2
case _ => -1
}
def main(args: Array[String]) {
println(func1("two"))
println(func2("two"))
}
}
package cn.doit.com.day03.demo06
object OptionDemo {
def main(args: Array[String]): Unit = {
val mp = Map("a" -> 1 , "b" -> 2)
//传入的参数如果找不到就会报错
// val r:Int = mp.apply("c")
// println(r)
//option代表这个参数有可能有,有可能没有
// val op:Option[Int] = mp.get("b")
//
// val r =op match {
// //如果有这个值返回这个值
// case Some(x) => x
// //如果没有这个值返回0
// case None => 0
// }
//有b返回b,没有返回-1 底层就是optionSomeNode 推荐使用
val r = mp.getOrElse("b",-1)
println(r)
}
}
package cn.doit.com.day03.demo06
object WordCount {
def main(args: Array[String]): Unit = {
val lines = Array("hadoop,flink,spark,hadoop,Hive", "hadoop,Flink,spark,Hadoop,spark")
val grouped = lines.flatMap(_.split(",")).groupBy(a => a.toLowerCase)
//元组中的元素特别多,容易混乱,使用模式匹配 match如果省略就要使用大括号
val a = grouped.map {
case (word, arr) => {
(word, arr.length)
}
}
println(a)
}
}