Scala模式匹配+异常+隐式转换+泛型+正则 笔记

模式匹配

package com.vanas.bigdata.java.chapter08;

import sun.java2d.pipe.SpanIterator;

/**
 * @author Vanas
 * @create 2020-05-30 9:05 上午
 */
public class TestSwitch {
    public static void main(String[] args) {
        int a = 10;
        //switch穿透现象 没跳出 继续执行
      	//穿透现象也有好处 可以简化 所以有歧义 
        switch (a){
            case  5:
                System.out.println("5");
            case  10:
                System.out.println("10");
            case  20:
                System.out.println("20");
            default:
                System.out.println("other");
        }
    }
}

scala模式匹配

package com.vanas.bigdata.chapter08

/**
 * @author Vanas
 * @create 2020-05-30 9:13 上午 
 */
object Scala01_Match {
    def main(args: Array[String]): Unit = {
        //case _的分支一般写在所有分支的最后,模仿default语法
        //如果所有的分支都不匹配,还没有case _分支,那么会发生错误
        var a: Int = 10
        var b: Int = 20
        var operator: Char = '+'
        var result = operator match {
        //放在前面的化反编译就不是 switch case
//          case _ => "illegal"
            case '+' => a + b
            case '-' => a - b
            case '/' => a / b
            case '*' => a * b
            case _ => "illegal"
        }
        println(result)

    }
}

模式匹配-规则

匹配列表

匹配数组

匹配常量

package com.vanas.bigdata.chapter08

/**
 * @author Vanas
 * @create 2020-05-30 9:13 上午 
 */
object Scala02_Match {
    def main(args: Array[String]): Unit = {
        //Scala-模式匹配-规则

        //匹配类型
        //下划线的作用省略参数,因为逻辑中不使用参数,所以可以省略
        //但是需要这个参数,那么可以起个名字
        //类型匹配不考虑泛型的:数组的泛型其实是类型的一部分
        //底层实现采用类型判断
        //val array=Array("1","2")
        val array = Array(1, 2, 3)
        //val list = List(1, 2, 3)
        val list2 = List(1, "2", 3, List(4, 5))
        val result = list2.flatMap(data => {
            //            List(data)
            data match {
                case a: List[_] => a
                case b => List(b)
            }
        })
        println(result) //List(1, 2, 3, 4, 5)

        //匹配数组
        for (arr <- Array(
            Array(0),
            Array(1, 0),
            Array(0, 1, 0),
            Array(1, 1, 0),
            Array(1, 1, 0, 1),
            Array("hello", 90))) {
            // 对一个数组集合进行遍历
            val result = arr match {
                case Array(0) => "0" //匹配Array(0) 这个数组
                case Array(x, y) => x + "," + y //匹配有两个元素的数组,然后将将元素值赋给对应的x,y
                case Array(0, _*) => "以0开头的数组" //匹配以0开头和数组
                case _ => "something else"
            }
            println("result = " + result)
        }

        //匹配列表
        for (list <- Array(
            List(0),
            List(1, 0),
            List(0, 0, 0),
            List(1, 0, 0),
            List(88))) {
            val result = list match {
                case List(0) => "0" //匹配List(0)
                case List(x, y) => x + "," + y //匹配有两个元素的List
                case List(0, _*) => "0 ..."
                case _ => "something else"
            }
            println(result)
        }

        val list: List[Int] = List(1, 2, 5, 6, 7)
        //val list: List[Int] = List(1, 2) //1-2-List()
        //val list: List[Int] = List(1) //something else
        list match {
            case first :: second :: rest => println(first + "-" + second + "-" + rest) //1-2-List(5, 6, 7)
            case _ => println("something else")
        }      
        //describe1(list) //List
        def describe1(x: Any) = {
            val result = x match {
                case i: Int => "Int"
                case s: String => "String hello"
                case m: List[_] => "List"
                case c: Array[Int] => "Array[Int]"
                case someThing => "something else " + someThing
            }
            println(result)
        }

        //匹配常量:final ,val
        def describe(x: Any) = {
            val result = x match {
                case 5 => "Int five"
                case "hello" => "String hello"
                case true => "Boolean true"
                case '+' => "Char +"
            }
            println(result)
        }
        describe(true)
    }
}

匹配元组

package com.vanas.bigdata.chapter08

/**
 * @author Vanas
 * @create 2020-05-30 9:13 上午 
 */
object Scala03_Match {
    def main(args: Array[String]): Unit = {
        //Scala-模式匹配-规则

        //匹配元组
        for (tuple <- Array(
            (0, 1),
            (1, 0),
            (1, 1),
            (1, 0, 2))) {
            val result = tuple match {
                case (0, _) => "0 ..." //是第一个元素是0的元组
                case (y, 0) => "" + y + "0" // 匹配后一个元素是0的对偶元组
                case (a, b) => "" + a + " " + b
                case _ => "something else" //默认
            }
            println(result)
        }
    }
}

匹配对象—样例类

package com.vanas.bigdata.chapter08

/**
 * @author Vanas
 * @create 2020-05-30 9:13 上午 
 */
object Scala04_Match {
    def main(args: Array[String]): Unit = {
        //Scala-模式匹配-规则

        //样例类
        //使用case关键字声明的类,称之为样例类
        //专门用于匹配对象
        //1.样例类在编译时,会自动生成伴生对象以及apply方法
        //2.样例类的构造参数默认使用val声明,所以参数其实就是类的属性
        //  如果想要更改属性,需要显示的将属性使用var声明
        //3.样例类会自动生成unapply方法
        //4.样例类会自动实现可序列化接口
        //在实际开发中,一般使用样例类,便于开发
        val emp = Emp("lisi",30)
//        emp.name="wangwu"
//        emp.age
        emp match {
            case Emp("lisi",30)=>println("xxxx")
            case  _=> println("yyyy")
        }

        //匹配对象
        //scala中模式匹配对象时,会自动调用对象的unapply方法进行匹配
        //这里的匹配对象,其实匹配的是对象的属性是否相同

        //val user = new User("zhangsan",20)
        val user = User("zhangsan", 20)
        val result = user match {
            case User("zhangsan", 11) => "yes"
            case _ => "no"
        }
        println(result)
    }
    //声明样例类
    case class Emp(var name:String,age:Int)
//    case class Emp(name:String,age:Int)
    //声明伴生类
    class User(val name: String, val age: Int)
    //声明伴生对象
    object User {
        //使用参数自动构建对象
        def apply(name: String, age: Int): User = new User(name, age)
        //使用对象自动获取参数
        def unapply(user: User): Option[(String, Int)] = {
            Option((user.name, user.age))
        }
    }
}

模式匹配应用

package com.vanas.bigdata.chapter08

/**
 * @author Vanas
 * @create 2020-05-30 9:13 上午 
 */
object Scala05_Match {
    def main(args: Array[String]): Unit = {
        //Scala-模式匹配-规则
        val list1 = List(("a", 1), ("b", 2), ("c", 3))
        val newList: List[(String, Int)] = list1.map(
            (t) => {
                (t._1, t._2 * 2)
            }
        )
        //模式匹配时,小括号需要变成花括号   可读性高
        //case后面的小括号不是参数列表的意思,表示元组
        //模式匹配一般就在一个参数的时候使用
        val newList1 = list1.map {
            case (word, count) => { //这么写可读性高,更好理解
                (word, count * 2)
            }
        }

        list1.filter {
            case (_, count) => {
                count == 2
            }
        }
        list1.flatMap {
            case (word, count) => {
                List(count)
            }
        }
        println(newList1)
  
        //模式匹配-集合元素
        val map1 = Map("a" -> ("aa", 1), "b" -> ("bb", 2))
        val list = List(1, 2, 3)
        //foreach方法将集合中每一个元素进行遍历
        //如果匹配集合中的元组数据时,匹配需要使用case关键字
        //list.foreach()
        map1.foreach(
            (kv) => {
                println(kv)
            }
        )
        map1.foreach {
            case (_, (_, count)) => {
                println(count)
            }
        }

        //模式匹配 -元组
        val (id, name, age) = (1, "zhangsan", 30)
        println(name)
      
      	//这么写长时间连自己都看不懂
        val data = (1, "zhangsan", 30)
        data._2
        val map = Map("a" -> ("aa", 1), "b" -> ("bb", 2))
        map.foreach(
            kv => {
                kv._2._2
            }
        )
    }
}

应用

package com.vanas.bigdata.chapter08

/**
 * @author Vanas
 * @create 2020-05-30 9:13 上午 
 */
object Scala06_Match {
    def main(args: Array[String]): Unit = {
        //Scala-模式匹配-应用
        val Array(first, second, _*) = Array(1, 7, 2, 9)
        println(first)

        val Person(name, age) = Person("zhangsan", 16)
        println(name)

        val map = Map("A" -> 1, "B" -> 0, "C" -> 3)
        for (kv <- map) {
            println(kv._1 + "," + kv._2)
        }

        for ((k, v) <- map) {
            println(k + "," + v)
        }

        //模式匹配还可以过滤数据
        for ((k, 0) <- map) {
            println(k)   //B
        }
    }
    case class Person(name: String, age: Int)
}

偏函数

使用的时候

package com.vanas.bigdata.chapter08

/**
 * @author Vanas
 * @create 2020-05-30 9:13 上午 
 */
object Scala07_Match {
    def main(args: Array[String]): Unit = {
        //Scala-模式匹配-偏函数
      
        val list = List(1, 2, 3, 4)
        //List(2,4,"3",8)
        val newlist: List[Int] = list.map(
            num => num * 2
        )
        println(newlist)
      
        //以偏概全
        //偏:部分
        //全:整体
        //所谓的偏函数就是对满足条件的一部分数据进行处理的数据
        //map函数不支持偏函数,支持全量函数操作
        val list1: List[Any] = List(1, 2, "3", 4)

        //声明偏函数:使用模式匹配进行数据处理 [输入,输出]
        val pf: PartialFunction[Any,Any] = {
            case i: Int => i * 2
            case s:String => s
        }
        //使用偏函数
        //调用支持偏函数的函数
        //collect:采集,支持偏函数
        val list2: List[Any] = list1.collect(pf)
        println(list2)

        //偏函数一般情况下可以使用模式匹配代替
        val list4 =List(1,2,"3",4)
        val newlist1=list4.collect{
            case i:Int =>i*2
            case s:String =>s
        }
        println(newlist1)
    }
}

将该List(1,2,3,4,5,6,“test”)中的Int类型的元素加一,并去掉字符串

package com.vanas.bigdata.chapter08

/**注意需求先后顺序 不可轻易更改
 * @author Vanas
 * @create 2020-05-30 9:13 上午 
 */
object Scala08_Match {
    def main(args: Array[String]): Unit = {
        val list = List(1, 2, 3, 4, 5, 6, "test")
//        list.map(
//            data=>{
//                data+1
//            }
//        )
      println(list.filter(_.isInstanceOf[Int]).map(_.asInstanceOf[Int] + 1))
    }
}

异常

什么是编译时异常和运行时异常?

编译时异常和运行时异常都是运行时产生的

所有的异常都是类

编译时异常可以理解为提示性异常

运行时异常 是意想不到的异常,可以通过编程的手段绕过去

error 和exception的区别?

异常可以处理的

error是无法恢复的

什么是空指针异常?

package com.vanas.bigdata.java.chapter09;

import java.util.List;

/**
 * @author Vanas
 * @create 2020-05-30 2:18 下午
 */
public class Java01_Exception {
    public static void main(String[] args) {
        User user = null; //NullPointerException
//        System.out.println(user);
        //空指针异常:调用一个为空(null)对象的成员方法或成员属性会发生空指针异常
        //JVM执行程序发生的错误,不是源码中的错误,是字节码运行的错误
        System.out.println(user.age);

        //age(Integer) =>test=>age(int)
        //拆箱操作可能会导致空指针异常
        //拆箱:Integer.intValue:(member)
				//test(user.age); //异常 NullPointerException

        //装箱Integer.valueOf(static) 底层是-128~127可以直接拿来用 其他就是new
        Integer i1 = 100;
        Integer i2 = 100;
        System.out.println(i1==i2); //true
        Integer i3 = 200;
        Integer i4 = 200;
        System.out.println(i3==i4); //false

        //包装类型的数据比较,一般有个equals方法
        //List.iterator:()(member)
        //所有可迭代的对象都可以使用增强for循环
        List list = null;
        for (Object obj : list) {
            System.out.println(obj);
        }
    }
    public static void test(int age) {
        System.out.println("年龄=" + age);
    }
}

class User {
    //public Integer age;
    public static Integer age;
    public static Integer id;
}

java异常

package com.vanas.bigdata.java.chapter09;

/**
 * @author Vanas
 * @create 2020-05-30 2:45 下午
 */
public class Java02_Exception {
    public static void main(String[] args) {
        try {
            //可能会发生异常的代码
            int i = 0;
            int j = 10 / i;
            //异常捕捉的顺序:先捕捉异常范围小的异常,然后再捕捉范围大的异常
        } catch (java.lang.ArithmeticException e) {
            System.out.println("java.lang.ArithmeticException....");
        } catch (Exception e) {
            //如果发生异常,处理的方案
            e.printStackTrace();
        } finally {
            //无论是否发生异常,都会执行的最终代码
            //资源的释放
        }
    }
}

scala异常

package com.vanas.bigdata.chapter09

import java.io.FileInputStream

/**
 * @author Vanas
 * @create 2020-05-30 2:52 下午 
 */
object Scala01_Exception {
    def main(args: Array[String]): Unit = {
        //scala中的异常和java的异常处理很相似
        //1.catch关键字只使用一次
        //2.多个异常采用case语法进行区分
        //3.异常处理的语法类似于模式匹配,所以匹配方式从前到后
        //  一般会将范围大的异常放置在范围小的异常后面进行处理
        //4.scala中的异常不分编译器异常和运行期异常,所以无需显示的处理和抛出
        //  scala中没有throws关键字
        try {
            val i = 0
            val j = 10 / i
            val s: String = null
            println(s.substring(1))
            new FileInputStream("xxxx")
        } catch {
            case e: ArithmeticException => {
                println("ArithmeticException...")
            }
//            case e: Exception => {
//                e.printStackTrace()
//            }
        } finally {

        }
    }
}

java中会明确异常

package com.vanas.bigdata.java.chapter09;

import com.vanas.bigdata.chapter09.Dept;

/**
 * @author Vanas
 * @create 2020-05-30 2:45 下午
 */
public class Java03_Exception {
    public static void main(String[] args) throws Exception {
        //Java在调用scala对象时,并没有明确处理异常
        //如果想要在处理时,明确异常的处理,那么需要在scala对象的方法前增加注解
        //@throws[异常类型]
        Dept dept = new Dept();
        dept.test();
    }
}

scala加注解 @throws[Exception]

package com.vanas.bigdata.chapter09

/**
 * @author Vanas
 * @create 2020-05-30 2:52 下午 
 */
object Scala02_Exception {
    def main(args: Array[String]): Unit = {
        //scala中的异常和java的异常处理很相似
    }
}
class Dept{
    @throws[Exception]
    def test()={
        throw new Exception
    }
}

隐式转换

package com.vanas.bigdata.chapter10

/**
 * @author Vanas
 * @create 2020-05-30 3:30 下午 
 */
object Scala01_Transform {
    def main(args: Array[String]): Unit = {
        //隐式转换

        val b: Byte = 10
        //Java中基本类型的数值之间存在精度的转换和截取
        //scala中没有精度的概念,编译时会自动由编译器调用java逻辑进行数值操作
        //两个类型如果想要互相转换,那么必须存在关系
        //1.父子类
        //2.接口和实现类

        //本来两个类型之间不存在关系,无法进行类型转换,但是编译器编译时
        //尝试找到对应的转换方法将类型进行转换,让程序编译通过
        //这个自动转换的过程称之为隐式转换,是由编译器完成的,也称之为二次编译
        val i: Int = b
//        val bb: Byte = i
        println(i)
    }
}

出现问题解决

package com.vanas.bigdata.chapter10

/**
 * @author Vanas
 * @create 2020-05-30 3:30 下午 
 */
object Scala02_Transform {
    def main(args: Array[String]): Unit = {
        //隐式转换
        implicit def transform(d: Double): Int = {
            d.toInt
        }
        //违背了OCP原则
        //编译器可以按照指定的规则进行查找,让错误的逻辑通过转换后,编译执行通过
        //这个功能称之为隐式转换
        //这里的隐式转换其实就是让编译器查找转换规则
        //如果想要编译器可以查找到转换规则,那么需要使用特殊的关键字implicit
        //这里的隐式转换其实就是 类型的转换 A=>B

        //隐式转化作用:
        //1.程序因为意外情况,导致正确的逻辑出现错误
        //2.扩展功能
        val i: Int = 2.0
//        val i: Int = transform(2)
//        val i: Int = 2.0.toInt
        println(i)
    }
}

扩展功能

package com.vanas.bigdata.chapter10

/**
 * @author Vanas
 * @create 2020-05-30 3:30 下午 
 */
object Scala03_Transform {
    def main(args: Array[String]): Unit = {
        //将User=>Parent
        //将函数声明前增加implicit关键字,可以由编译器自动识别和自动调用
        //完成类型的转换,并扩展功能
        //这种方法称之为隐式方法
        implicit def transform(user: User): Parent = {
            new Parent()
        }
//        implicit def transform1(user: User): Parent = {
//            new Parent()
//        }

        //1.如果当前范围内,有多个相同的转换规则怎么办?
        //  转换无法成功,因为编译器无法识别用哪一个
        //  相同的转换规则只能有一个
        //2.隐式转换方法调用的时机?
        //  二次编译:第一次编译会出现错误时,会选择隐式转换

        //动态混入
        //val user = new User() with Parent
        val user = new User()
        user.insertUser()
        user.updataUser() //1.编译出错 2.编译器查找转换规则 3.再次编译

    }
    class Parent {
        def updataUser(): Unit = {
            println("updata user")
        }
    }

//    trait Parent { //继承也能通过 但还是违反OCP
//        def updataUser(): Unit = {
//            println("updata user")
//        }
//    }
    class User {
        def insertUser(): Unit = {
            println("insert user")
        }
    }
}

隐式参数 隐式变量

柯里化的时候使用较多

package com.vanas.bigdata.chapter10

/**
 * @author Vanas
 * @create 2020-05-30 3:30 下午 
 */
object Scala04_Transform {
    def main(args: Array[String]): Unit = {

        //OCP

        //函数的参数预先知道可能会发生变化,为遵序OCP开发原则
        //可以给函数增加关键字修饰一下
        //implicit修饰函数的参数时,这个参数所在的参数列表只能有一个参数

        //隐式参数
        def regUser(name: String)(implicit password: String = "123456"): Unit = {
            println(s"注册用户:$name,默认密码:$password")
        }

        //隐式变量
        implicit val pswd:String ="000000"
        //如果使用隐式参数进行处理,那么调用函数时,不需要使用小括号调用
        //如果使用小括号,隐式变量无法使用
        regUser(name = "zhangsan")()

        val list = List(1,4,3,2)
        list.sortBy(num=>num)(Ordering.Int.reverse)
        list.sortBy(num=>num)

        val s = "abc" //string =>char[]=>char(0)
        println(s(0)) //a
        //StringOps 其实是字符串的一个辅助类,增加功能,靠隐式转换实现
    }
}

隐式类

直接在类中一次性完成,更加方便

其实是对隐式转换函数的简化

package com.vanas.bigdata.chapter10

/**
 * @author Vanas
 * @create 2020-05-30 3:30 下午 
 */
object Scala05_Transform {
    def main(args: Array[String]): Unit = {
//        implicit def transform(user: User): UserExt = {
//            new UserExt
//        }

        val user = new User()
        user.insertUser()
        user.updataUser()
    }
    //隐式类
    //scala2.10版本中增加此功能
    //构造参数必须存在且只有一个,用于转换类型
    //参数类型(User)=>当前类型(UserExt)
    implicit class UserExt(user:User) {
        def updataUser() = {
            println("updata user...")
        }
    }
    class User {
        def insertUser() = {
            println("insert user...")
        }
    }
}

隐式转换的查找规则

1.在当前作用域

2.在相关类型的伴生对象中

package com.vanas.bigdata.chapter10

/**
 * @author Vanas
 * @create 2020-05-30 3:30 下午 
 */
object Scala06_Transform {
//object Scala06_Transform extends Test {
    def main(args: Array[String]): Unit = {
        //隐式转换的查找规则
        //隐式类不能放置在顶级(top-level)对象中
        //1.当前代码的作用域中找到即可
        //2.当前代码上级作用域
        //3.当前类所在的包对象
        //4.当前类的父类或特质
        //如果想用隐式转换,那么直接导入
        import com.vanas.bigdata.chapter01.Scala06_ImplicitClass._

        val user = new User()
        user.insertUser()
        user.updataUser()
    }
//    implicit class UserExt07(user: User) {
//        def updataUser() = {
//            println("updata  07 user...")
//        }
//    }
    class User {
        def insertUser() = {
            println("insert user...")
        }
    }
}
//trait Test {
//    implicit class UserExt06(user: User) {
//        def updataUser() = {
//            println("updata 06 user...")
//        }
//    }
//}
//class Test {
//    implicit class UserExt06(user: User) {
//        def updataUser() = {
//            println("updata 06 user...")
//        }
//    }
//}
//implicit class UserExt(user:User) {
//    def updataUser() = {
//        println("updata user...")
//    }
//}
package com.vanas.bigdata

/**
 * @author Vanas
 * @create 2020-05-30 4:49 下午 
 */
package object chapter10 {
//    implicit class UserExt05(user: User) {
//        def updataUser() = {
//            println("updata  05 user...")
//        }
//    }
}
package com.vanas.bigdata.chapter01

import com.vanas.bigdata.chapter10.Scala06_Transform.User

object Scala06_ImplicitClass {

    implicit class UserExt(user: User) {
        def updataUser() = {
            println("updata user...")
        }
    }
}

为什么不加括号

package com.vanas.bigdata.chapter10

/**
 * @author Vanas
 * @create 2020-05-30 3:30 下午 
 */
object Scala07_Transform {
    def main(args: Array[String]): Unit = {
        def transform( implicit  d : Double ) = {
            d.toInt
        }
        implicit val dd : Double = 2.0

        //含有隐式参数的方法,在调用时如果不使用小括号,那么表示使用隐式变量
        //如果使用小括号,那么表示放弃使用隐式变量
        val result:Int =transform
        println(transform) //2
    }
}

泛型

package com.vanas.bigdata.java.chapter11;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author Vanas
 * @create 2020-06-01 8:53 上午
 */
public class Java01_Generic {
    public static void main(String[] args) {
        //泛型-JDK1.5
        //泛型类
        //泛型方法
        //类型约束
        List list1 = new ArrayList();
        List<String> list = new ArrayList<String>();

        //类型擦除
        //JVM没有泛型的概念,所以泛型其实在编译器层次起作用
        List<Integer> list2 = new ArrayList<Integer>();
        //test(list);
        //泛型的问题
        //数据类型和使用的泛型不是一个层面的东西
        //如果能够泛型转换的化,那么底层就会出现类型转换
        //那么可能会出现风险,编译器不允许这种情况出现
        List<String> stringList = new ArrayList<String>();
        //test(stringList);

        //泛型的使用
        //为了让泛型使用的更加方便,java提供了特殊操作
        //< ? extends User > or < ? super User >
        //泛型其实在两个维度进行类型的操作
        //外部类型:List
        //内部类型:<String>
        //如果内部类型相同,那么类型是可以存在上下级关系的
        test1(stringList);
    }
    public static void test1(Collection<String> list) {
    }
    public static void test(List<Object> list) {
    }
}

泛型的使用

package com.vanas.bigdata.java.chapter11;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author Vanas
 * @create 2020-06-01 8:53 上午
 */
public class Java02_Generic {
    public static void main(String[] args) {
        //泛型
        //泛型不可变
        //AAA<User>aaa1 =new AAA<Parent>();
        AAA<User> aaa2 = new AAA<User>();
        //AAA<User>aaa3 =new AAA<SubUser>();
        //AAA<User>aaa4 =new AAA<Emp>();
        System.out.println(aaa2);

        //泛型的上限,下限
        BBB bbb = new BBB();
        List<Parent> parentList = new ArrayList<Parent>();
        List<User> userList = new ArrayList<User>();
        List<SubUser> subUserList = new ArrayList<SubUser>();
        List<Emp> empList = new ArrayList<Emp>();
//        bbb.extendsTest(parentList); error
        bbb.extendsTest(userList);
        bbb.extendsTest(subUserList);
//        bbb.extendsTest(empList); error

        bbb.superTest(parentList);
        bbb.superTest(userList);
//        bbb.superTest(subUserList); error
//        bbb.superTest(empList);  error

        //泛型上限,下限使用的场景
        //泛型上限一般用于对获取的数据进行限定
        CCC<User> ccc = new CCC<User>();
        CCC<SubUser> ccc2 = new CCC<SubUser>();
        Message<? extends User> consume = ccc.consume();
        User t = consume.t;
        //泛型下限一般用于插入数据的类型限定
        DDD<User> ddd = new DDD<User>();
        ddd.producet(new Message<User>());
        ddd.producet(new Message<Parent>());
    }
}
class DDD<T> {
    public void producet(Message<? super T> m) {

    }
}
class Message<T> {
    public T t;
}
class CCC<T> {
    public Message<? extends T> consume() {
        return null;
    }
}
class BBB<T> {
    //泛型的上限
    public void extendsTest(List<? extends User> list) {
    }
    //泛型的下限
    public void superTest(List<? super User> list) {
    }
}
class AAA<T> {
}
class Parent {
}
class User extends Parent {
}
class SubUser extends User {
}
class Emp {
}

scala中的泛型

package com.vanas.bigdata.chapter11

/**
 * @author Vanas
 * @create 2020-06-01 8:52 上午 
 */
object Scala01_Generic {
    def main(args: Array[String]): Unit = {
        //泛型
        //不要求自己写,能看懂就行
        //泛型一般在框架中使用,为了考虑通用性
        //默认Scala中的泛型和java是一致的
        //scala声明泛型,采用的中括号
        //泛型不可变
        //[T]
        //val a1: AAA[User] = new AAA[Parent] error
        val a2: AAA[User] = new AAA[User]
        //val a3: AAA[User] = new AAA[SubUser] error
        //al a4: AAA[User] = new AAA[Emp] error

        //泛型协变:将泛型作为类型的一部分来理解
        //泛型可以将子类型当成父类型使用
        //BBB[SubUser] 当成BBB[User]子类型
        //[+T]
        //val b1: BBB[User] = new BBB[Parent]
        val b2: BBB[User] = new BBB[User]
        val b3: BBB[User] = new BBB[SubUser]
        //val b4: BBB[User] = new BBB[Emp]

        //泛型逆变 :将泛型作为类型的一部分来理解
        //泛型可以将父类型当成子类型使用
        //CCC[Parent]当作CCC[User]子类型
        //[-T]
        val c1: CCC[User] = new CCC[Parent]
        val c2: CCC[User] = new CCC[User]
        //val c3: CCC[User] = new CCC[SubUser]
        //val c4: CCC[User] = new CCC[Emp]

        //泛型上限
        //[<:]
        val ddd = new DDD()
        //ddd.test1[Emp](new Emp()) //error
        //ddd.test1[Parent](new Parent()) //error
        ddd.test1[User](new User())
        ddd.test1[SubUser](new SubUser())
        //泛型下限
        //[>:]
        //ddd.test2[Emp](new Emp()) //error
        ddd.test2[Parent](new Parent())
        ddd.test2[User](new User())
        //ddd.test2[SubUser](new SubUser()) //error

        //具体例子
        val list = List(1, 2, 3, 4)
        //将数据统计结果变为:1234
        //List(1,2,3,4) =>"1"+"2"+"3"+"4"="1234".toInt
        //A =>Int
        //A1 >:A =>AnyVal,Any
        //(A1,A1 )=>A1
        //val i: Int = list.reduce()
        val list1: List[Any] = "" +: list //List("",1,2,3,4)
        val result: Any = list1.reduce(
            (x, y) => {
                x + y.toString
            }
        )
        println(result.toString.toInt)

        val strings: List[String] = list.map(num => num.toString)
        println(strings.reduce(_ + _).toInt)

        //fold方法要求数据处理类型和初始值的类型之间应该有关系 //类型一样有fold
        val lon: AnyVal = 10
        val b: Byte = 10
        //list.fold("")(_+_) //error  fold A1 A1 =>A1
//        val l: Long = list.fold(lon)(
//            (x, y) => {
//                x
//            }
//        )
//        list.fold[Byte](b) { 
//            (x, y) => {
//                x
//            }
//        }

        //foldLeft数据处理类型和初始值的类型无关  //不一样用foldLeft
        val str: String = list.foldLeft("")(_ + _)
        println(str.toInt)

        //两个map合并
        //map kv
        val map1 = Map("a" -> 1, "b" -> 2)
        val map2 = Map("a" -> 1, "b" -> 2)
        map1.fold(map2) {
            (map, kv) => {
                map
            }
        }
        map1.foldLeft(map2) {
            (map, kv) => {
                map
            }
        }
    }
    class DDD {
        //泛型上限(范围越来越小)
        def test1[T <: User](t: T) = {
        }
        //泛型下限(范围越来越大)
        def test2[T >: User](t: T) = {
        }
    }
    class CCC[-T] {
    }
    class BBB[+T] {
    }
    class AAA[T] {
    }
    class Parent {
    }
    class User extends Parent {
    }
    class SubUser extends User {
    }
    class Emp {
    }
}
package com.vanas.bigdata.chapter11

/**
 * @author Vanas
 * @create 2020-06-01 8:52 上午 
 */
object Scala02_Generic {
    def main(args: Array[String]): Unit = {
        //看懂
        def f[A: Test](a: A) = println(a) //Test[a]
        //将泛型和隐式转换合二为一
        implicit val test: Test[User] = new Test[User]
        f(new User())
    }
    class Test[T] {
    }
    class Parent {
    }
    class User extends Parent {
    }
    class SubUser extends User {
    }
}

正则表达式

package com.vanas.bigdata.chapter12

import scala.util.matching.Regex

/**
 * @author Vanas
 * @create 2020-06-01 10:41 上午 
 */
object Scala01_Regex {
    def main(args: Array[String]): Unit = {
        //正则表达式
        //类似于模式匹配
        //模式匹配是对数据进行匹配
        //正则表达式对字符串的内容进行匹配
        //有自己的匹配规则

        //声明规则
        val r: Regex = "s".r
        val r1: Regex = "s$".r

        //使用规则
        val s = "hello hive"
        r findFirstIn s
        val maybeString: Option[String] = r.findFirstIn(s)
        //r.findAllIn(s)
        //r.findAllMatchIn(s)
        if (maybeString.isEmpty){
            println("没有符合规则的内容")
        }else{
            println(maybeString.get)
        }
        //判断字符串是不是一个电话号码
        //1.全部都是数字
        //2.数字长度11位
        val r2: Regex = "^\\d{11}$".r
        val s1 = "01514021200"
        val maybeString1: Option[String] = r2.findFirstIn(s1)
        if (maybeString1.isEmpty){
            println("没有符合规则的内容")
        }else{
            println(maybeString1.get)
        }
    }
}

分布式案例

package com.vanas.bigdata.chapter13

/**
 * @author Vanas
 * @create 2020-06-01 11:00 上午
 */
object Calc {
    def main(args: Array[String]): Unit = {
        val num = 5
        var sum = 0
        val start: Long = System.currentTimeMillis()
        //串行
        //并发(资源共享)单点资源资源有限对硬件要求高 与串行效率差别不大
        //并行(分布式) 
        for (i <- 1 to num) {
            new Thread(
                new Runnable {
                    override def run(): Unit = {
                        sum = sum + i * 2
                        Thread.sleep(i * 100)
                    }
                }
            ).start()
        }
        val end: Long = System.currentTimeMillis()
        println(
            s"""
               |计算结果为:$sum,耗时:${end - start}ms
               |""".stripMargin
        )
    }
}

分布式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VnK79umh-1592735308937)(https://tva1.sinaimg.cn/large/007S8ZIlgy1gfcqc9jg3sj31ck0nq7ad.jpg)]

进程与进程通信连接很慢,长时间连接占用资源 效率低

所以client和server的概念就淡化了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kbklYf9u-1592735308938)(https://tva1.sinaimg.cn/large/007S8ZIlgy1gfcqcgn1alj31h80oedmw.jpg)]

如果数量多的话 找中间解耦合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aZmfsuVA-1592735308939)(https://tva1.sinaimg.cn/large/007S8ZIlgy1gfcqcp61qjj31j60n8gta.jpg)]

Driver
package com.vanas.bigdata.chapter13

import java.io.{ObjectInputStream, ObjectOutputStream}
import java.net.{ServerSocket, Socket}

/**
 * @author Vanas
 * @create 2020-06-01 11:00 上午
 */
object Driver {
    def main(args: Array[String]): Unit = {
        //数据准备
        val executorCount = 5
        val myHost = "localhost"
        val myPort = 1234

        //连接资源中心
        val resourceCenterRef = new Socket("localhost", 9999)
        println("资源中心已连接,数据准备中")
        val resourceCenterRefOut = new ObjectOutputStream(resourceCenterRef.getOutputStream)
        resourceCenterRefOut.writeObject(
            Message(s"executorCount=$executorCount&driverHost=$myHost&driverPort=$myPort"))
        resourceCenterRefOut.flush()
        //释放和资源中心的连接
        resourceCenterRef.close

        //接收Executor端的数据
        //线程安全问题
        //val sum =0
        val results: Array[Int] = Array.fill(executorCount)(-1)

        val receiver = new ServerSocket(myPort)

        new Thread(
            new Runnable {
                override def run(): Unit = {
                    //统计结果的线程
                    var flg = true
                    while (flg) {
                        if (results.contains(-1)) {
                            Thread.sleep(100)
                        } else {
                            //所有的线程都已经计算完毕
                            println("计算完毕,结果为:" + results.sum)
                            flg = false
                            System.exit(0)
                        }
                    }
                }
            }
        ).start()

        while (true) {
            val executorRef: Socket = receiver.accept()
            println("执行器已经连接..")
            new Thread(
                new Runnable {
                    override def run(): Unit = {
                        //向Excutor发送计算任务
                        val executorRefOut = new ObjectOutputStream(executorRef.getOutputStream)
                        val task = new Task()
                        task.logic = _* 2
                        executorRefOut.writeObject(task)
                        executorRefOut.flush()
                        executorRef.shutdownOutput()

                        //获取Excutor端计算结果
                        val executorRefIn = new ObjectInputStream(executorRef.getInputStream)
                        //val result: Int = excutorRefIn.readObject().asInstanceOf[Int]
                        //println("获取计算结果:" + result)
                        val m: Message = executorRefIn.readObject.asInstanceOf[Message]
                        val datas: Array[String] = m.content.split("=|&")
                        results(datas(1).toInt - 1) = datas(3).toInt
                    }
                }).start()
        }
    }
}

Excutor
package com.vanas.bigdata.chapter13

import java.io.{ObjectInputStream, ObjectOutputStream}
import java.net.Socket

/**
 * @author Vanas
 * @create 2020-06-01 11:00 上午
 */
case class Excutor(id: Int, driverHost: String, driverPort: Int) {
    //启动执行器
    def startup() {
        println(s"执行器$id 开始启动")

        println(s"执行器$id 开始连接驱动器")
        val dirverRef = new Socket(driverHost, driverPort)
        //接收Driver端发送的计算任务的数据
        val dirverRefIn = new ObjectInputStream(dirverRef.getInputStream)
        val task: Task = dirverRefIn.readObject().asInstanceOf[Task]
        dirverRef.shutdownInput()
        //执行计算
        val i: Int = task.logic(id)
        //将计算结果返回给Driver
        val driverRefOut = new ObjectOutputStream(dirverRef.getOutputStream)
        driverRefOut.writeObject(Message(s"executorId=${id}&result=$i"))
        driverRefOut.flush()
        dirverRef.close()
    }
}

Message
package com.vanas.bigdata.chapter13

/**
 * @author Vanas
 * @create 2020-06-01 11:00 上午
 *         样例类自动实现序列化接口
 *         自动生成伴生对象
 */
case class Message(val content: String)

ResourceCenter
package com.vanas.bigdata.chapter13

import java.io.ObjectInputStream
import java.net.{ServerSocket, Socket}

/**
 * @author Vanas
 * @create 2020-06-01 11:00 上午
 */
object ResourceCenter {
    def main(args: Array[String]): Unit = {
        //连接资源 中心
        //1.创建服务,接收资源请求
        val reciver = new ServerSocket(9999)
        println("资源中心已经启动。。")
        while (true) {
            val driverRef: Socket = reciver.accept()
            new Thread(
                new Runnable {
                    override def run(): Unit = {
                        //接收Driver传递的数据
                        val driverRefIn = new ObjectInputStream(driverRef.getInputStream)
                        val message: Message = driverRefIn.readObject().asInstanceOf[Message]
                        //executorCount =$executorCount&driverHost=$myHost&driverPort=$myport
                        //分解字符串,应该同时使用 = ,&
                        //使用正则表达式分解字符串
                        val datas: Array[String] = message.content.split("=|&")
                        val executorCount = datas(1).toInt
                        val driverHost = datas(3)
                        val driverPort = datas(5).toInt
                        for (i <- 1 to executorCount) {
                            val executor = new Excutor(i,driverHost,driverPort)
                            executor.startup()
                        }
                    }
                }
            ).start()
        }
    }
}
Task
package com.vanas.bigdata.chapter13

/**
 * @author Vanas
 * @create 2020-06-01 2:11 下午 
 */
class Task extends Serializable {

    var data: Int = 0
    var logic: Int => Int = null
  
    def compute() = {
        logic(data)
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值