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
//内部类型:
//如果内部类型相同,那么类型是可以存在上下级关系的
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) {
//泛型
//泛型不可变
//AAAaaa1 =new AAA();
AAA<User> aaa2 = new AAA<User>();
//AAAaaa3 =new AAA();
//AAAaaa4 =new AAA();
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)]
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()
}
}
}
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()
}
}
package com.vanas.bigdata.chapter13
/**
* @author Vanas
* @create 2020-06-01 11:00 上午
* 样例类自动实现序列化接口
* 自动生成伴生对象
*/
case class Message(val content: String)
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()
}
}
}
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)
}
}