当前位置: 首页 > news >正文

泰安网站建设公司宝安做网站公司乐云seo

泰安网站建设公司,宝安做网站公司乐云seo,平价建网站,网站数据模版1.scala简介 2004年#xff0c;martin ordersky发明#xff0c;javac的编译器#xff0c;后来spark,kafka应用广泛#xff0c;twitter应用推广。它具备面向对象和函数式编程的特点。 官网#xff1a;www.scala-lang.org,最近版本2.12.5#xff0c;我们用的是2.10.42.环境…1.scala简介 2004年martin ordersky发明javac的编译器后来spark,kafka应用广泛twitter应用推广。它具备面向对象和函数式编程的特点。 官网www.scala-lang.org,最近版本2.12.5我们用的是2.10.42.环境安装 1) windowsa) 安装jdk-7u55-windows-x64.exeb) 安装scala-2.10.4.msi安装完以上两步不用做任何修改。测试在控制台下c:/scalac) 安装eclipse-java-juno-SR2-win32-x86_64.zip 解压缩即可d) 安装eclipse的scala插件update-site.zip解压会有两个目录features和plugins分别把内容放到eclispe对应的目录下。 e) 重启eclipse提示Upgrade of scala...点yes提示框setup Diagnostic把Enable JDT weaving...选上根据提示重启 2) linux3.第一个程序 1) 交互式编程C:\Users\AdministratorscalaWelcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_5Type in expressions to have them evaluated.Type :help for more information.scala 11res0: Int 22) 脚本形式:通过创建文件来在eclipse/idea中执行代码object Test {def main(args: Array[String] ) {println(Hello world)}}注1上面这个是单例对象这个里面只能存放静态的东西注2自动导入2个包java.lang._scala._注3语句最后一行的分号不推荐写4.基础语法 1) 变量和常量 val(常量)和var(变量) 尽可能的用val(1) 变量格式var 变量名 [:数据类型] 值例var b :Int 1var c 2 //类型自动推断(2) 常量格式val 常量名 [:数据类型] 值例val b :Int 1val b 1b 2 //报错常量不能修改(3) 常量可以用lazy修饰(了解)lazy val b :Int 1 //b用到的时候再赋值2) 数据类型 (1)数据类型序号 数据类型 说明1 Byte 8位有符号值范围从-128至1272 Short 16位有符号值范围从-32768至327673 Int 32位有符号值范围从-2147483648至21474836474 Long 64位有符号值范围从-9223372036854775808至92233720368547758075 Float 32位IEEE 754单精度浮点值6 Double 64位IEEE 754双精度浮点值7 Char 16位无符号Unicode字符。范围从U0000到UFFFF8 String 一个Char类型序列9 Boolean 文字值true或文字值false10 Unit 对应于无值等价于void类型只有一个对象叫()11 Null 只有一个对象叫null12 Nothing 在Scala中处于最底层比如创建数组时不指定类型就是Noting。抽象概念13 Any 任何类型的超类型; 任何对象的类型为Any14 AnyRef 任何引用类型的超类型(2)层次结构Scala.Any-AnyVal(值)-Int,Double等Unit。-AnyRef(引用)-List,Set,Map,Seq,Iterable-java.lang.String-Null(3)重点类型元组格式(元素1, 元素2, ....)访问变量._N 其中N是元组元素的索引从1开始例var t (a, false, 1) //t的类型是scala.Tuple3var value t._1 //avar m,n,(x,y,z) (a, false, 1) m :(a, false, 1) n :(a, false, 1)x : ay : false:z : 1(4)重点类型字符串i) 用的是java.lang.String但是有时候根据需要会隐式转换到其它类型比如调用reverse/sorted/sortWith/drop/slice等方法这些方法定义在IndexedSeqOptimized中ii)多行字符串表示开始和结束用(4)重点类型字符串i)用的是java.lang.String,但是有时候根据需要会隐式转换到其它类型比如调用reverse/sorted/sortWith/drop/slice等方法这些方法定义在IndexedSeqOptimized中ii)多行字符串表示开始和结束用(5)了解符号类型符号字面量 标识符,是scala.Symbol的实例,像模式匹配类型判断会比较常用。var flag startif (flag start) println(1) else println(2)3) 运算符:scala没有运算符它运算符全部封装成了方法。 算术 - * / %比较: ! 逻辑 || !赋值 - * /* %位 | ~ ^ #*/注上面都是方法。例 12相当于1.(2)其中是方法2是参数4) 控制语句 (1) ifif...else...if...else if...else...(2) scala中的if可以作为表达式用var x if(hellohell) 1 else 0(3) switch被模式匹配替换5) 循环语句 (1)while,do..while和for都有while和do..while很像但是for差别很大。(2)for循环格式不同for(变量 - 集合 if 条件判断1;if 条件判断2...) {所有条件判断都满足才执行}(3)没有break和continue用两种方法可以代替i) 用for循环的条件判断ii)方法2:非写break要做以下两步//1) 引入一个包scala.util.control.Breaks._//2) 代码块用breakable修饰breakbreakable {for(i-0 to 10) {println(i)if (i 5) {break;}}}//0 1 2 3 4 5continuefor(i-0 to 10) {breakable {if (i 3 || i6) {break;}println(i)}}//0 1 2 4 5 7 8 9 10(5) 集合框架(ArrayList,Set,Map)在scala中数组Array归到集合的范畴包scala.collection下面有两个分支immutable(不可改变的,默认)和mutable(可变的)(1) 层次结构Traversable-Iterable(immutable不可改变的长度默认)-Set 无序的集合没有重复元素HashSet,TreeSt 其中HashSet内部定义了别名Set-Map 键值对映射HashMap,TreeMap 其中HashMap内部定义了别名Map-Seq 序列。有先后顺序的元素集合-IndexedSeqArray有索引的元素序列因此可以通过下标访问VectorString,Range-LinearSeqList线性的元素序列。访问第1个元素head方法最后1个tail方法Queue,Stack(mutable可变的长度)-SetHashSet 其中HashSet内部定义了别名Set-MapHashMap 其中HashMap内部定义了别名Map-Seq-IndexedSeqArraySeq,StringBuilder-BufferArrayBuffer,ListBuffer-LinearSeqLinkedList,QueueStack重点记忆几个不可变 可变Array ArrayBufferList ListBufferMap MapSet Set(2) 数组(非常重要)数据类型相同的元素按照一定顺序排序的集合。不可变数组 scala.Array可变长数组 scala.collection.mutable.ArrayBufferArray和ArrayBuffer1.Array创建var 变量名 new Array[类型](长度) //var arr new Array[Int](10)var 变量名 Array(元素1,元素2,...) //var arr Array(1,3,5,7)实际上是调用Array的方法apply取值变量名(下标)2.ArrayBuffer创建var 变量名 new ArrayBuffer[类型]() //var arr new ArrayBuffer[Int]()var 变量名 ArrayBuffer(元素1,元素2,...) //var arr ArrayBuffer(1,3,5,7)3.共同方法sum 求和max 最大值min 最小值mkString(分隔符) 例Array(1,3,5,7).mkString(|) //结果是1|3|5|7|9sorted 排序(从小到大)sortBysortWith 自定义排序reverse 翻转toArray ArrayBuffer转成ArraytoBuffer Array转成ArrayBuffertoMap如果Array内部元素是对偶元组可以转成maptoList转成list4.ArrayBuffer的独有方法 追加元素 追加集合trimEnd(n):删除末尾n个元素insert(index,value1,value2,..valueN):第index的位置插入value1,value2,...valueN)remove(index,n):第index个位置删除n个元素clear():清空5.遍历i) 通过下标for (i - 0 to 数组.length-1) {println(i)) //i表示数组的下标}ii)直接取值for (e - 数组) {println(e)}6.使用yield创建新数组var arr for (i - 数组) yield i * 27.多维数组var arr Array(Array(元素1...),Array(元素,...)..)遍历for (i - arr) {for (j - i) {println(j)}} (3) List(不可变)/ListBuffer(可变)List 和java.util.List不同一旦创建不可以改变。一般做数据分析用List1.List定义//创建var list1 List(aa,bb,ccc) //调用apply方法var list2 List.apply(aa,bb,ccc))//右操作符当方法名以:结尾时为右操作符,先做右边//::右操作符拼接元素,var list3 aa::bb::cc::Nil //Nil是空集合先做cc::Nil其中::是Nil的方法var list4 list1:::dd::Nil //:::拼接集合2.常用方法//查head() 第一个元素take(n) 取前n个元素tail() 除了第1个的全部元素init() 除了最后一个的全部元素//增:和: 前者是尾部追加元素后者是在头部追加元素和::很像或append 追加元素(ListBuffer) 追加数组/列表(ListBuffer):: 追加元素(List)::: 追加数组/列表(List)//删drop(n) 丢弃前n个元素//改 updated(index,value):用value地替换第index的位置的元素//其他isEmpty是否为空reverse 翻转splitAt(m):把列表前m个做成一组后面是一组flatten:以参数的列表作为参数把所有的元素连接到一起//toArray 转成ArraytoArray 转成Arrayzip:两个List内部的元素合并,返回结果是List元素是对偶元组grouped(n):每n个元素分成1组,返回是迭代器Iterator可以再用toList转成list类型3.ListBufferimport scala.collection.mutable.ListBuffervar list5 ListBuffer(111,222,333)(4) Set不存在重复元素的集合如果用可变的需要引入import scala.collection.mutable.Set//定义var s Set(3.0, 1.0)//追加元素s 2.0 //s s 2.0s 2.0 //元素重复加不进去(5) Map//定义var m1 Map((zhang3,20),(li4,23),(wang5,21)) //使用元组var m2 Map((zhang3-20),(li4-23),(wang5-21))var m3 Map[String,Int]() //定义空map得用可变的才有意义。//添加和更新 var m scala.collection.mutable.Map((zhang3, 20), (li4, 23), (wang5, 21))m ((zhao6, 22)) //m m.updated(zheng7,19) //和上面方法一样m.put(wu, 22) m Map((a - 1), (b - 2))//删除m - ((zhao6, 22))m.clear() 清空//查询m(key)通过key获取valuem.get(key) 通过key获取value,返回类型Optionm.getOrElse(key,获取不到设置的值)//其它size:元素个数contains(key):是否包含key返回布尔类型keys 返回迭代器keySet 返回所有的key组成的Set集合values 返回迭代器,所有value组成的集合mapValues(函数)foreach(函数)//遍历(6) Array和List都是不可变元素有什么区别5.函数 Scala中函数和方法在类中定义的函数就是方法。 1) 函数声明 def 函数名([参数列表]):[返回类型] {函数体return [表达式]}注1如果函数没有返回值可以返回Unit也可以不写注2方法的返回类型可以不写系统自动推导但是递归必须写。注3函数体的大括号只有一行可以不写例def add(a:Int,b:Int):Int {var sum : Int 0sum a breturn sum}2) 函数调用 格式方法之间调用函数名([实参列表]) 例add(3,5)对象之间调用实例名.函数名([实参列表]) 例s.add(3,5)3) 值函数 (1)定义var 变量名:[输入类型输出类型] {(参数列表){函数体}}其中是函数映射符在参数列表后不能写返回值类型最后一句不能写returnLambda表达式(匿名函数函数字面量):形如(参数列表){函数体}就叫Lambda表达式4) 高阶函数 1) 定义本身是函数参数也是函数或返回值是函数例1def m(f:(Double)Double):Double {f(100)}def sqrt(x:Double)Math.sqrt(x)调用m(sqrt) 结果是10.02) 常见高阶函数集合中常见的高阶函数(1)map def map[B, That](f: A B): That 把函数应用于集合中的每一个元素把返回由返回值组成的一个集合。例Array(spark,hive,haddop).map((x:String)x.length)Array(spark,hive,haddop).map(xx.length)Array(spark,hive,haddop).map(_.length) // _占位符代表一个元素Array(spark,hive,haddop).map(xprintln(x))Array(spark,hive,haddop).map(println _)Array(spark,hive,haddop).map(println) //如果只有一个参数可以不写(2) flatMap把函数应用于集合中的每一个元素先做map,得到的结果flatten生成新的集合。例var list List(a,b,c,d,e,f)var list2 list.map(xx.split(,).toList) //List(List(a, b, c), List(d, e, f))list2.flatten //List(a,b,c,d,e,f)上面两步可以写成一步,相当于mapflatternlist.flatMap(xx.split(,).toList) //简写list.flatMap(_.split(,).toList)问map和flatMap有什么区别(3)filter参数的函数表示对集合的每个元素过滤参数函数结果是boolean最后的返回值还是ListList(1,2,3,4).filter(xx2) //List(3,4)Array(1,2,3,4,5,6,7,8).filter(xx%20) //取偶数 2,4,6,8Range(1,100).filter(_%20) //1到100的偶数Array(1,2,3,4,5,6,7,8).filter(xx%20).map(_*10)//20,40,60,80注filterNot和filter相反(4)reduce/reduceLeft/reduceRight返回1个值。参数函数要求是二元运算符作用于集合上每次返回的结果作为新的输入。Array(1,3,5,7).reduce((x,y){println(x : y);xy})Array(1,3,5,7).reduce(__) //第1个_代表第1个参数第2个_代表第2个参数Array(1,3,5,7).reduceLeft((x,y){println(x : y);xy})Array(1,3,5,7).reduceRight((x,y){println(x : y);xy})注reduce没有特别的顺序reduceLeft从左到右计算reduceRigth从右到左计算(5)fold/foldLeft/foldRight和reduce很像只是增加了一个初始值,但是做并行时要注意。Array(1,3,5,7).fold(4)(__) //20List(2.0,3.0).fold(4.0)(Math.pow) //4096.0(6) par把计算转换为并行化把reduce拆分多个任务Array(1,3,5,7,8).par.fold(4)(__)Range(1,10).par.map(println)(7) groupBy 对列表进行分组,返回结果是mapvar data List((zhang3,male),(li4,female),(wang5,male))data.groupBy(xx._2) //Map(male- List((zhang3,male), (wang5,male)), female - List((li4,female)))多介绍一个grouped(n):每n个分成一组例List(1,3,5,7,9).grouped(2).toList //List(List(1, 3), List(5, 7), List(9))(8)partition把列表分成两部分第一个为满足条件的第二部为不满足条件的List(1,3,5,7,9).partition(xx4) //分成两组(List(5, 7, 9),List(1, 3))(9)diff差集,union并集并保留重复,intersect交集var n1 List(1,2,3)var n2 List(2,3,4)var n3 n1.diff(n2) //也可以写n1 diff n2 结果:List(1)var n4 n2.diff(n1) //List(4)var n5 n1 union n2 //List(1 2 3 2 3 4)var n6 n1 intersect n2 //List(2,3)(10)distinct去掉重复元素List(1,2,3,2,3,4).distinct // List(1, 2, 3, 4)(11)mapValues(函数)还是map功能只是处理的值是value最终结果是mapMap((zhang3,20),(li4,23),(wang5,21)).mapValues(_*2)//结果Map(zhang3 - 40,li4 - 46,wang5 - 42)(12)foreach(函数)和map一样区别是它没有返回值通常用在遍历(13)sorted 排序和sortBy和sortWithsorted 排序最简单从小到大List(2,1,3,5,6,4).sorted //1 2 3 4 5 6sortBy:按照第几列排List((a,3),(b,1),(c,2)).sortBy(_._2) //按照第2列排sortWith:自定义排序List(2,1,3,5,6,4).sortWith((x,y)xy) //从大到小3)下划线_的用法(1) 让匿名函数更简洁可以用下划线_当做一个占位符。(2) java中导入包下的所有类用*在scala中用_例Java: import java.util.*scala: import java.util._(3) 下划线_可以作为部分应用函数4) 函数柯里化柯里化(curring) 把接收多个参数的函数编程接收一个单一参数例1不是柯里化但是和柯里化很像def foo(factor : Int) (x:Double)factor * x;调用var f foo(10)f(50)也可以直接写foo(10)(50)例2柯里化def foo(factor : Int)(x:Double) factor * x调用foo(10)(50)注柯里化函数不是高阶函数不能这么调用var f foo(10)5)部分应用函数(Partial Applied Function)部分应用函数, 是指一个函数有N个参数, 而我们为其提供少于N个参数, 那就得到了一个部分应用函数.,柯里化函数和普通函数都有部分应用函数6)偏函数(Partial Function)(1)简介引子scala List(1,2,3) map {case i:Inti1}scala List(1,2,3) map {(i:Int)i1}上面两个结果是一样的。偏函数:上面例子中map后面的被包在花括号内的代码也就是没有 match的一组case语句就叫偏函数。偏函数类型是PartialFunction[A,B]A的参数类型B是返回结果类型。平常我们都是直接用。例1val foo : PartialFunction[Int,String] { //类型PartialFunction[Int,String]可以省略case y if y % 2 0 y 是偶数}println(foo(10)) //10 is Evenprintln(foo(11)) //抛出错误 scala.MatchError----反编译:相当于foo是一个对象调用对象的 apply方法private final PartialFunction foo new PartialFunction{public final Object apply(int i){Object obj;if (i % 2 0)obj y 是偶数elseobj i;return obj;}}foo.apply(10) (2)orElse可以把多个偏函数结合起来,效果类似case语句。val or1 {case 1 One}val or2 {case 2 Two}val or_ {case _ Other}val or or1 orElse or2 orElse or_ //使用orElse将多个偏结合起来//测试scala or(1) // one scala or(20) //other(3) andThen: 相当于方法的连续调用比如g(f(x))。 val a {case cs if cs 1 One}val b {case cs if cs eq One The num is 1}val c a andThen b//测试num(1) //The num is 1(4) 普通函数的偏应用函数定义比如我先定义一个函数:def sum(a:Int,b:Int,c:Int) a b c;那么就可以从这个函数衍生出一个偏应用函数是这样的:def foo sum(1, _:Int, _:Int) 调用foo(2,3), 相当于调用sum(1,2,3) 两个_分别对应函数sum对应位置的参数. 用处当你在代码中需要多次调用一个函数, 而其中的某个参数又总是一样的时候, 使用这个可以少敲一些代码(5)柯里化函数中的偏应用函数定义def sum(a:Int)(b:Int)(c:Int) a b c; // (a: Int)(b: Int)(c: Int)Intval result sum _ //柯里化赋值结果是部分应用函数 Int (Int (Int Int)) function1sum(1)(2)(3) //6result(1)(2)(3) //6result(1)(_: Int)(3) //部分应用函数Int Int function12018/4/56.面向对象 1) 类和对象 (1) 简介scala中的类和java中的类一样都是通过class定义class Person { //不写public默认public//var name:String; //报错变量必须要被初始化而java不需要被初始化系统会自动赋初值var name :String null //正确var age :Int _ //正确不知道赋上面值时用_占位符}(2)创建对象var p1 new Person()var p2 new Person //没有参数可以省略()(3) 类成员访问p1.name zhang3 //设置,底层调用的是p1.name_(zhang3)其中_是方法println(p1.name) //取值非要用getter和setter属性前加入 BeanProperty(导入包scala.beans._)(4) 单例对象scala中不支持静态成员的语法通过单例对象实现object Test {private var id:Int 0def m() {id 1id}}测试scalaTest.m //1scalaTest.m //2(5) 伴生对象和伴生类单例对象和类如果同名的话单例对象也叫伴生对象。例class A {}object A {}伴生对象和伴生类可以互相访问即使是private也可以访问但是private[this]不能访问一个文件可以有多个类(6) apply方法object Dog {def apply():Unit {println(1)}def apply(name:String):Unit {println(2)}def main(args: Array[String]) { var d1 Dog() //调用Apply()方法var d2 Dog(hello) //调用Apply(String)方法}}2) 主构造方法 (1)定义每个类都有主构造方法参数放在类名后构造方法和类交织在一起。class Student(var name:String, var age:Int) 反编译代码public class Student {private String name;private int age;public Student(String name, int age) {println(hello: name)this.name name;this.age age;}//getter和setter//name()和name_$eq(String)//age()和age_$eq(int)Overridepublic String toString() {return name : age}} Student s new Student();System.out.println(s) //打印s就是打印s.toString()例class Student(var name:String, var age:Int) {println(hello) //加在主构造方法中override def toString name : age}var s new Student()println(s)(2) 带有默认参数的主构造方法构造方法可以带有默认参数。class Student(var name:String, var age:Int, val gender:Stringfemale) {println(执行主构造方法)}var s1 new Student(zhang3, 18, male) //正确var s2 new Student(li4, 18) //正确s2.name wang5s2.gender male(3) 私有构造方法class Student private(var name:String, var age:Int)var s new Student(li4, 18)//报错3) 辅助构造方法 (1) 非主构造方法方法名用this(2) 非主构造方法也可以有默认值class Dog(val id:String) {var name :String 大黄def this(id:String,name:String) {this(id) this.name name}override def toString name : id}//测试var d1 new Dog(1111)var d2 new Dog(2222,二黄)println(d1)println(d2)4) 继承和多态 (1) 继承用extendsclass Person(var name:String, var age:Int)//没有写var表示继承父类的属性class Student(name:String,age:Int, var no:String) extends Person(name,age)//测试new Person(tom, 18)new Student(jack,19,123)Student从父类继承name和age所以前面不要加变量var或者val,no是新加的元素所以需要var(2) 多态多种形态动态绑定在执行期间确定引用对象的实际类型根据其实际类型调用相应的方法也就是子类可以赋值给父类。· class Human(var name:String, var age:Int) {def walk():Unit {println(walk in Human)} }class Teacher(name:String,age:Int) extends Human(name,age) {override def walk():Unit {println(walk in Teacher)} }class Doctor(name:String,age:Int) extends Human(name,age) {override def walk():Unit {println(walk in Doctor)} }//测试var x:Human new Teacher(tom, 18)var y:Human new Doctor(jack, 19)x.walk //walk in Teachery.walk //walk in Doctor5) 成员访问控制 private 类内伴生对象protected 同包子类不写默认是public都可以访问特别之处(1) private[this] 只能类内访问class Person {private[this] var name:String zhang3 //只能类内private var age: Int 18 //类内伴生对象}object Person {def main(args:Array[String]) {var p new Personprint(p.age) //18//print(p.name) //报错}}(2) 主构造方法也可以加入成员访问控制class Person(private var name:String, protected var age:Int)6) 抽象类 不能能被实例化的类。可以有抽象方法非抽象方法成员变量。但是scala增加了抽象成员变量。abstract class Person {var name:String //抽象成员变量def walk //抽象方法}//子类如果继承必须要实现抽象变量和抽象方法如果不想实现子类也需要是抽象类class Student extends Person {override var name:String _ //覆盖父类的抽象变量override def walk():Unit {println(walk in Student)} //覆盖父亲的抽象方法}7) 内部类和内部对象 定义在对象或者类内部的类object Ex extends App {class Student(var name:String, var age:Int) { //内部类class Grade(var name:String)//内部对象object Utils {def print(name:String) println(name)}}object Student {//内部类class Printer {def print(name:String) println(name)}}var s new Student(tom, 18)//var grade new Student.Grade(xxx) //此处出错怎么纠正s.Utils.print(student:util.print(String))new Student.Printer().print(Student.Printer().print(String))}8) 匿名类 没有名字的类一般用在某个类只在代码出现一次abstract class Person(var name:String, var age:Int) {def print():Unit}//调用//var p new Person(tom, 18) //错误抽象类不能new也就是不能创建实例var p new Person(tom, 18) {def print():Unit println(hello)}p.print();9) trait(特质),其实就是接口相当于jdk1.8的接口比jdk1.8以下版本的接口多了非抽象的变量和方法 (1) scala没有提供接口interface而用trait关键字其实和接口等价。使用方法extends或with第一个实现的特质用extends之后的用with它和抽象基本一样可有抽象成员抽象方法具体成员和具体方法例trait Closeable {def close():Unit}trait Clonable {def open():Unit}//第一个接口用extends后面的用withclass File(var name:String) extends Closeable with Clonable{def close():Unit println(file close)def open():Unit println(file open)}//写一个全的traittrait Book {var a : Long _ //具体成员var b : Long //抽象成员def add(x:Int) //抽象方法def add2(x:Int):Int x2 //具体方法}var b new Book(){ //定义匿名内部类,只需要实现抽象方法和抽象成员变量即可override var b : Long 1def add(x:Int) println(x)}b.add(6)println(b.add2(5))10) 自身类型(self type) trait A {val a 1}trait B {this:A //引入接口A相当于把A的东西全放进来var b 2def xx() {println(this.a : this.b)}}class C extends B with A//调用new C().xx()//还有一种特殊用法this定义别名class D {self //为this定义别名self也可以是其他名字var x 2def foo self.x this.x}//常见用法,用在内部类引用外部类的变量class OuterClass {xx //为this定义别名var value hereclass InnerClass {println(xx.value)}}7.包 1) 包定义 (1) 第一种定义方式和java很像package cn.cda.day1(2) 第二种定义方式package cn{package cda {package day1 {class Teacher {}}package day2 {class Student}}}以上方式不推荐2) 作用域 scala中有private,proteced和默认(public)外还有private[x]和protected[x],其中x可以是包/类/单例对象3) 包对象 通过package关键字声明的对象为保对象主要用于对常量和工具函数的封装通过包名引用。package object Math {val PI 3.14}class Test {def main(args:Array[String]) {m(3) //3.14*928.62}def m(r:Double) Math.PI * r * r}4) import 导入包下的所有的类和对象还可以引入重命名和类隐藏等功能。1) 隐式导入默认导入的包通过下面命令查看scala:import2) 引入重命名import java.util.{HashMapJavaHashMap}import scala.collection.immutable.HashMapvar map new JavaHashMap3) 类隐藏引入java.util.下的所有类但是不想要HashMapimport java.util.{HashMap_,_} //隐藏HashMapimport scala.collection.immutable.HashMapvar map new HashMap8 模式匹配 1) 简介 模式匹配类似switch语言简单用法就是替代多层的if else语句和类型检查和快速匹配。它使用了关键字match来替换switch一旦匹配到了后面不再执行所以不用break语句。scala有一个十分强大的模式匹配机制可以用到很多场合。如switch类型检查等格式case 变量: 类型 代码例java和scala进行比较 --javafor (int i 1; i 5 ; i) {switch (i) {case 1:System.out.println(1);break;case 2:System.out.println(2);//不带break会陷入其它分支同时输出2,3case 3:System.out.println(3);break;default:System.out.println(default);//case语句不能接表达式//case i%50:System.out.println(10)}}--scalafor (i - 1 to 5) {i match {case 1 println(1) //不需要写break,case 2 println(2)case 3 println(3) case _ println(default)}}//上面的case语句中还可以加入表达式for (i - 1 to 5) {i match {case 1 println(1) //不需要写break,case x if (x%2 0) println(s$x 是偶数) //加入表达式 ,此时的x是形参,i是实参 case _ //这句话表示其它任何情况都不进行操作}}//还可以作为函数体def m(x:Int) x match {case 5 整数5case y if (y % 2 0) 能被2整除 //注意y认为是形参case _ 其它整数}println(m(5)//反编译public String m(int x){switch (x){default: tmpTernaryOp 其它整数; break;}return x % 2 0 ? 能被2整除 : 整数5;} 2) 模式匹配的7大类型 (1)常量模式case后面接的全部是常量例for (i - 1 to 5) {i match {case 1 println(1) //不需要写break,case 2 println(2)case 3 println(3) case _ println(default)//可以写成 case x}}(2)变量模式case后面接的是变量例def m(i:Int) i match {case x if (x % 2 0) 能被2整除 //这个顺序是有关系的case x if (x % 3 0) 能被3整除 case x 能被2或3意外的数 // 等价于 case _}//调用println(m(5))println(m(4))println(m(3)) (3)构造方法模式与创建对象相反见下例1case class Dog(val name:String, val age:Int)def m(x:AnyRef) x match {case Dog(name,age)println(name:age)// 构造函数模式与创建对象相反对对象进行析构调用unapply方法普通类没有case类系统会生成。case _}//测试val dog Dog(Pet, 2) //调用apply创建对象m(dog)例2对部分变量析构case class Dog(val name:String, val age:Int)def m(x:AnyRef) x match {case Dog(_,age)println(age) //表示匹配这个成员域但是不需要使用nam的值case _}(4)序列模式用于匹配Seq集合的用法和上面类似但是可以使用_*来匹配多个元素并且只能放在模式内的最后例def m(x:AnyRef) x match {case Array(a,b)println(1)case Array(a,_,b,_*)println(2) //_匹配第2个元素,_*匹配任意多只能放模式最后case _}//调用 m(Array(1,2,3,4))(5)元组模式和上面用法相似但是不能使用_*,_*只能在序列模式中使用。例def m(x:AnyRef) x match {case (a,b)println(1)case (a,_,b,_)println(2)//case (a,_*)//元素模式不能使用_*case _}var t (1,2,3,4)m(t)(6)类型模式匹配变量的类型class Aclass Bclass C extends Adef m(x:AnyRef) x match {case y:Stringprintln(1)case y:Bprintln(2)case y:Aprintln(3)case _println(4)}//测试val b new Bval c new Cm(hello)m(b)m(c)反编译源代码 public void m(Object x){if ((x instanceof String)){this.println(1);}else if ((x instanceof B)){this.println(2);}else if ((x instanceof A)){this.println(3);}else {this.println(4);}}(7)变量绑定模式如果想要的不是析构对象而且返回匹配模式的对象,很常用例1case class Dog(val name:String,val age:Int){override def toStringname:age}def m(x:AnyRef) x match { //Dog(_,_)用于匹配输入对象中包括两个成员变量的Dog对象匹配成功后把对象赋值给dcase dDog(_,_) println(变量绑定模式返回的变量值 d)case _}// 测试val dog new Dog(Pet, 2)m(dog)反编译源代码public void m(Object x) {if ((x instanceof Dog)){Dog d (Dog)x;this.println(变量绑定模式返回的变量值 d)}else {}}例2:更常见也更复杂val list List(List(1,2,3,5),List(4,5,6,7,8,9))def m(x:AnyRef) x match {//变量绑定模式case e1List(_,e2List(4,_*))println(e1: e1 ,e2: e2)case _}//调用 m(list)//e1:List(List(1, 2, 3, 5), List(4, 5, 6, 7, 8, 9)),e2:List(4, 5, 6, 7, 8, 9)---反编译代码public void m(Object x) { if ((x instanceof List)){List e1 (List)x;Some localSome1 List..MODULE$.unapplySeq(e1);if ((!localSome1.isEmpty()) (localSome1.get() ! null) (((LinearSeqOptimized)localSome1.get()).lengthCompare(2) 0)){Object e2 ((LinearSeqOptimized)localSome1.get()).apply(1);if ((e2 instanceof List)){List localList2 (List)e2;Some localSome2 List..MODULE$.unapplySeq(localList2);if ((!localSome2.isEmpty()) (localSome2.get() ! null) (((LinearSeqOptimized)localSome2.get()).lengthCompare(1) 0)){Object localObject2 ((LinearSeqOptimized)localSome2.get()).apply(0);if (BoxesRunTime.equals(BoxesRunTime.boxToInteger(4), localObject2)){Predef..MODULE$.println(new StringBuilder().append(e1:).append(e1).append(,e2:).append(localList2).toString());localBoxedUnit BoxedUnit.UNIT; return;}}}}}}3) 正则表达式与模式匹配(略) (1)Scala正则表达式 (2)正则表达式在模式匹配中的应用4) for循环种的模式匹配 (1)变量模式匹配for((x,y)-Map(a-1,b-2,c-3)) {println(x : y)}(2) 常量模式匹配//下面只有b被匹配到输出2for((b,y)-Map(a-1,b-2,c-3)) {println(y)}(3) 变量绑定模式匹配//可以绑定变量xxx和yyyfor((xxxb,yyyy)-Map(a-1,b-2,c-3)) {println(xxx : yyy)}(4) 类型模式匹配//类型value为字符串才能匹配到for((x,y:String)-Map(a-1,b-hello,c-3)) {println(x : y)}(5) 构造方法模式匹配case class Dog(val name:String, val age:Int)case class Cat(val name:String, val age:Int)for (Dog(name,age) - List(Dog(a,1),Cat(b,2),Dog(c,3))) {println(name : age)}上面输出第1个和第3个for (List(first,_*) - List(List(1,2,3), List(4,5,6,7))) {println(first)}(6) 序列模式匹配可以用_*5) 样例类和样例对象 样列类(case class)使用case修饰的类。就是增加了一些方法比如unapply。用在上面的模式匹配. 1) 样例类是一种特殊的类可以用于模式匹配。case class是多例,case object是单例。上面已经做了一个例子了下面再做一个例子用到了sealted.trait中前面加入 seatled表示密封类a) 其修饰的traitclass只能在当前文件里面被继承b) 并且用sealed修饰这样做的目的是告诉scala编译器在检查模式匹配的时候让scala知道这些case的所有情况scala就能够在编译的时候进行检查看你写的代码是否有没有漏掉什么没case到减少编程的错误。例sealed trait Acase class B(id:String,name:String) extends Acase class C(id:String) extends Acase class D(id:String) extends Adef m(x:A) x match {case B(id,name)1case C(id)2 // 这一行如果不写系统会警告这样的好处是提示你不要漏了case D(id)3} //测试val b new B(1,zhang3)println(m(b))// 注意如果注释掉上面的B,C,D中的任何一句系统会警告所以在子类众多的时候要用 sealed修饰带来的好处。2) 样例对象(case object)上面看到每个子类都有自己的属性但是实际开发可能不需要属性如果不定义属性编译器会警告。这时候需要定义样例对象(case object)来声明sealed trait Acase class B(id:String,name:String) extends Acase class C(id:String) extends Acase class D(id:String) extends Acase object E extends Adef m(x:A) x match {case B(id,name)1case C(id)2 case D(id)3case E4} //测试val b new B(1,zhang3)println(m(b))println(m(E)) //直接调用分析a)case class会先创建对象而case object可以直接使用b)case class会生成两个字节码文件而case object是一个c)case class生成的伴生对象会自动实现 apply和unapply方法而case object不会使用 case object可以提高速度减少开销 例2spark中的一段代码如下看学生是否看懂import scala.util.Randomcase class SubmitTask(id: String, name: String)case class HeartBeat(time: Long)case object CheckTimeOutTask //定义样例对象object Test extends App {var arr Array(CheckTimeOutTask, HeartBeat(2333), SubmitTask(0001, task-001));arr(Random.nextInt(arr.length)) match {case SubmitTask(id, name) { println(s$id,$name) }case HeartBeat(time) { println(time) }case CheckTimeOutTask { println(check) }}3) Option类型Option类型也是样本类表示值是可选的要么无值要么有值Option的子类有Some和None用Some(x) 表示有值x是真正的返回值用None表示无值val map Map(cn-1,jp-2) val v map.get(cn) match { //get方法返回 Option类型case Some(i) icase None 0}查看map集合的源代码 def get(key: A): Option[B]查看some的源代码case class Some[A](x: A) extends Option[A] 查看None的源代码case object None extends Option[Nothing] {我们常用 getOrElse(c,0)9 隐式转换 1)隐式转换简介 scala提供的一种强大的语法特征必须掌握。开发中会自动转换。scala定义了一些隐式转换会自动导入他们。比如 1 to 5 调用 1.to(5)但是to并不是Int类型的方法它会自动转换为 scala.runtime.RichInt源代码系统自动导入Predef对象在scala.Predef中objectPredef父类LowPriorityImplicits中方法intWrapper(x:Int)new runtime.RichInt(x)不仅如此 Int还可以转换为其它类型(AnyRef,Integer,Double,Float,Long)可以由其它类型转换而来查看所有的隐式转换scala:implicit -vscala.Int的伴生对象包含了Int到其它类型的转换implicit def int2long(x:Int) : Long x.toLongimplicit def int2float(x:Int) : Float x.toFloatPredef对象中也可以了大量的隐式转换函数如Scala数值类型到java数值类型的转换implicit def byte2Byte(x:Byte) java.lang.Byte.valueOf(x)正是这些隐式转换函数的存在简化了Scala代码。 2) 隐式转换 (1)隐式转换函数Scala默认提供了大量的隐式转换比如Int到Float,但是如果想实现Float到Int需要自己定义例val value : Int 1.0f // 报错修改implicit def m(x:Float) x.toInt //toInt方法有但是没有隐式转换val value : Int 1.0f原理当编译机发现类型不匹配就会查找隐私转换函数--------xjad反编译----------- public int m(float x){return (int)x;}int value m(1.0F);System.out.println(value); }注名称可以是任意(与参数类型和返回值有关)但不要重复否则隐式转换报错不过尽量给名字写的有意义(2) 隐式类隐式类的转换不像隐式转换函数那么明显。例;implicit class A (val name:String) { def bark println(name is barking)}//调用Nacy.bark //由于String没有 bark方法因此会找隐式类由于A的主构造方法是String就会调用。---源代码 public static class Test$A{private final String name;public Test$A(String name) {this.name name}public void bark(){System.out.println(name is barking)}} public final class Test${public void main(String args[]){new Test.A(Nacy).bark();//把“nacy”转换为创建A的对象}}(3) 隐式对象单例对象前加入implicit关键字trait A[T] {def m(x:T):T }//隐式转换对象整数的平方implicit object AInt extends A[Int]{def m(x:Int) x * x}//隐式转换对象字符串的乘积implicit object BString extends A[String] {def m(x:String) x * 2}//定了一个函数函数具有泛型参数def foo[T:A](x:T) {val obj implicitly[A[T]] //通过 implicitly方法知道T的类型创建A的相应子类对象obj.m(x)}//调用println(foo(5)) //25,从下面源代码可以看到翻译成java时传递两个参数println(foo(5))//55------源代码----public final class Test${public Object foo(Object x, Test.A o) { //传递A的子类对象Test.A obj (Test.A)(o);return obj.m(x);}public void main(String args[]) {foo(5,传递Test.AInt的单例对象);}}public final class Test{interface A{Object m(Object obj);}}public static class AInt implements A{public int m(int x){ return x * x; }}public static class BString implements A{public String m(String x){ return x * 2}}(4) 隐式参数 上面的implicitly方法换一种形式定义在参数中 参数前加了implicit这种形式的参数成为隐式参数上面代码可以化简如下def foo[T:A](x:T)(implicit obj:A[T]) { //知道T的类型创建A的相应子类对象obj.m(x)}//编译后的源代码基本不变(5) 隐式值隐式值也叫隐式变量前面用implicit修饰例1:implicit val x : Double 2.55def sqrt(implicit y: Double) Math.sqrt(y)//测试 scala sqrt //不指定参数编译器再当前作用于查找相应的隐式值或隐式对象找到x传给它--xjad反编译public final class Test${private final double x 2.5499999999999998D; public double sqrt(double y) {return Math.sqrt(y);}public void main(String args[]){sqrt(x);}}例2改写上面的代码trait A[T] {def m(x:T):T }class AInt extends A[Int]{ //普通类def m(x:Int) x * x}class BString extends A[String] {def m(x:String) x * 2}implicit val a new AInt //隐式值,上面的例子是隐式对象implicit val b new BStringdef foo[T:A](x:T)(implicit obj:A[T]) { obj.m(x)}//调用println(foo(5)) //25println(foo(5))//553) 隐式参数使用常见问题 1. 当函数没有柯里化implicit关键字组用于函数列表中的所有参数scaladef m(implicit x:Double,y:Double) x * y //所有参数都作用implicitm: (implicit x: Double, implicit y: Double)Doublescalaimplicit val d 2.5scalam //结果 6.252. 隐式函数使用时要么全部指定要么全不指定不能只指定部分如果上面调用scalam(3.0) 就报错scalam(3.0,3.0)3. 同类型的隐式值只在当前作用域内出现1次如果再定义 scalaimplicit val d2 3.5scalam // 报错 4. 在定义隐式函数时implicit关键字只能在参数开头//报错不能定义在第2个参数def m(x:Double,implicit y:Double) x * y 5. 如果想达到函数def m(x:Double,implicit y:Double)只将参数y定义为隐式函数的目的需要对函数柯里化//柯里化后只有参数y是隐式参数def m(x:Double)(implicit y:Double) x * yimplicit val d 4.0m(3)6. 柯里化的函数implicit关键字只能作用于最后一个参数def m(x:Double)(y:Double)(implicit z:Double) x * y * z //正确def m(implicit x:Double)(y:Double)(z:Double) x * y * z //错误没有作用于最后一个 7. implicit关键字只在隐式参数中出现1次对柯里化的函数也不例外def m(implicit x:Double,implicit y:Double) x * y // 错误8. 匿名函数不能使用隐式参数val m (x:Double, y:Double)x * y // 正确val m (implicit x:Double, y:Double)x * y9. 柯里化的函数如果有隐式参数则不能使用其偏应用函数def m(x:Double)(y:Double) x * yval t1 m _ //赋值给t1, 定义两个参数的偏函数t1(3,0)(4,0)val t2 m(3.0) _t2(4.0)以上都没有问题但是如果下面有隐式参数则会报错 def m(x:Double)(implicit y:Double) x * yval p m _ //报错4)隐式转换规则与问题 (1) 隐式转换的若干规则a) 作用域规则必须在当前作用域才能起作用。c) 无歧义规则不能存在两个一样功能的隐式转换函数。d) 一次转换原则只经过1次隐式转换不能经过多次(2) 是否调用隐式转换非必要的情况下尽量少用如果是为了炫耀大胆使用。10 类型参数 1) 简介 (1) 简介在类的声明中定义一些泛型然后在类内部就可以使用这些泛型类型。scala泛型和java泛型基本相同只是Java语法格式为而Scala语法给是为[]//比如 java中ListT ,而Scala中为 List[T]//比如trait Map[A,B] extends Iterable[(A,B)] with GenMap[A,B] with scala.collection.Map[A,B] {override def empty:Map[A,B] Map.empty} (2) 泛型类class Person[T](var name :T)class Student[T,S](name:T, var age:S) extends Person(name)//name前不写var表示继承例新生入学填写id时候有的人用整数有的人用字符串class Student[T](val id:T) {def get(hukouId:T) id hukouId}val a new Student[Int](111)a.get(4)val a new Student(111) //不写Int可以自动推断val a new Student[String](111)//测试class Student[A,B](var name:String, var age:Int)println(new Student[String,Int](a,1).name)(3) 泛型方法与泛型类类似给某个函数在声明时指定泛型类型def getCard[T](content: T) {if (content.isInstanceOf[Int]) 1 //等价于java的instanceOfelse if (content.isInstanceOf[String]) 2else 3}//测试getCard(111) //1getCard(222) //2getCard(false) //3(4) 类型通配符在java中采用List?来做但是scala中没有采用上面的特性是通过存在类型来解决类[T,U,..] forSome {type T;type U;...}例//存在类型Array[T] forSome {type T}def printAll(x : Array[T] forSome {type T}) {for (i - x) {println(i)}}---源代码public void printAll(Object x) {Predef$.MODULE$.genericArrayOps(x).foreach(new Serializable() {public final void apply(Object i) {System.out.println(i);}});}//可以写简化形式def printAll(x : Array[_]) {for (i - x) {prntln(i)}} 2) 类型变量界定 对泛型范围进行界定而不是任意类型。比如必须是某个类的子类或者是父类才能正常使用。java中这么定义//List? extends Object 接收object的子类包括Object//List? super Integer 接收Integer的父类包括Integerscala没有采用它采用对应::例1class Person(val name: String) {def makeFriends(other: Person) println(this.name 和 other.name 交朋友)}class Student(name: String) extends Person(name)class Party[T : Person](p1: T, p2: T) {def play p1.makeFriends(p2)}//调用var p1 new Student(zhang3)var p2 new Student(li4)new Party[Student](p1, p2).play例2 def compare[T :Comparable[T]](first:T,second:T) {//表示Comparable的子类if (first.compareTo(second)0) firstelsesecond}调用compare(A,B”) //B3) 视图界定 用%表示 相当于上面的:加上隐式转化class Person(val name: String) {def makeFriends(other: Person) println(this.name 和 other.name 交朋友)}class Teacher(var name: String)class Party[T % Person](p1: T, p2: T) {def play p1.makeFriends(p2)}implicit def teacher2Person(t: Teacher) : Person new Person(t.name)//调用var p1 new Teacher(zhang3)var p2 new Teacher(li4)new Party[Teacher](p1, p2).play4) 上下文界定 回顾以前: 继承要求是长辈: 继承要求是低辈% 继承隐式转换 这次T:A T是一个泛型 A是个类要求调用这个类的函数时必须要隐式引入A[T]。举个例子T是整数IntA是Ordering(理解成排序comparator,系统有这个类)要求使用时候要引入隐式值Ordering[Int]class Test[T:Ordering](val a:T,val b:T) {def bigger(implicit myComparator:Ordering[T]) {if (myComparator.compare(a,b)0)println(a : myComparator.getClass)elseprintln(b)}}new Test(1,2).bigger //2----反编译----public class Test{private final Object a;private final Object b;public Test(Object a, Object b,){this.a a;this.b b; }public void bigger(Ordering myComparator){if (myComparator.compare(a(), b()) 0)System.out.println(a());elseSystem.out..println(b());}}new Test(1,2).bigger(系统自带的实现Int的Ordering对象) 5) 多重界定 (1) T:A:B 隐式引入A[T],B[T](2) T%A%B 存在T到AT到B的隐式转换(3) T1:T:T2 T1是T类型的超类T2也是T类型的超类class A[T]class B[T]implicit val a new A[String]implicit val b new B[String]//1.当前作用域中必须存在两个隐式值类型为 A[T],B[T]def test[T:A:B](x:T) println(x) test(测试1)implicit def t2A[T](x:T) new A[T]implicit def t2B[T](x:T) new B[T]//2.当前作用域中必须存在T到AT到B的隐式转换def test2[T % A[T] % B[T]](x:T) println(x)test2(测试2)6) 协变与逆变 //解决问题如果Child是Father的子类那么ListChild是不是ListFather的子类答案:不是但这会造成很多问题。但Scala只要灵活运用协变与逆变就可以解决这个问题协变 T 当A是B的子类 那么func(A) 是func(B)的子类例:class Fatherclass Child extends Fatherclass Test[T]var x new Test[Father]var y new Test[Child]//此事x也是y的父亲x y //正确y x //错误逆变 -T当A是B的子类 那么func(A) 是func(B)的父类11 scala并发编程基础(讲义已经单独做成doc文档:讲义-Actor编程.docx) 1) 简介 (1) 并发和并行 并发在一台处理器上“同时”处理多个任务一个时刻只有一个任务跑 并行在多台处理器上同时处理多个任务一个时刻有有个任务跑。 优化并发增加进程或者线程纵向扩展并行增加cpu横向扩展Actor模型可以同时解决纵向和横向扩展
http://wiki.neutronadmin.com/news/201234/

相关文章:

  • 如何用电脑主机做网站广州市官网网站建设多少钱
  • 佛山营销网站建设咨询网业进不去什么原因
  • seo网站优化推广怎么做如何修改wordpress的字体
  • 电子商务网站功能设计与分析网站运营工作是干什么的
  • 你建立的网站使用了那些营销方法鲁中网站
  • 网站怎么优化呢网络营销岗位技能
  • 横岗做网站公司大庆市最新公告
  • 舟山网站建设企业昆山市住房和城乡建设局网站
  • 内蒙古网站建设信息做二手车网站需要什么
  • 无锡网站建设维护邯郸广告公司网站建设
  • 做网站的流程视频线上营销模式有哪些
  • 微信的官方网站怎么做wordpress登录界面插件
  • 昆山门户网站九江集团网站建设公司
  • 专业做ppt的网站做网站送白酒
  • 天津网站建设费用磁力链最佳的搜索引擎
  • 怀化招标网站WordPress文章百度收录插件
  • 网站推送怎么做的网站建设手机站
  • 源码网站下载wordpress标签统一
  • 金华浦江网站建设下述不属于网页制作工具
  • 简单描述一下网站制作的流程网站建设栏目分级
  • 房屋中介做网站的温州网站搭建
  • 建行手机网站网址是多少钱wordpress主题演示站
  • 青海网站建设与制作网站建设实训记录
  • 德州网站推广wordpress国内工作室主题
  • 企业网站信息化建设工程建设企业等采用
  • 用wordpress搭建网站休闲农业有哪些网络营销方式
  • 佛山市网站建设 乾图信息科技提升自己建设自己的网站
  • 个人摄影网站模版火车头采集器发布wordpress
  • 百万网站建设报价制作个人网站论文
  • 网站制作用什么编程网站优化是往新闻中心发新闻吗