实时金融、计费系统更倾向于使用 storm。
Scala基础语法 :
scala函数:
函数的定义与调用:
函数1:
函数2:
默认参数 :
带名参数:
传参 时未命名参数放到最左边:
变长参数:
使用序列调用变长参数:
因为1 to 5 是Range类型,而我们定义 的sum这个函数入参为Int类型,所以要进行特殊转换。
过程
lazy值:
但是输入一个并不存在的文件会报错:
def lines 也报错。
异常:
数组:
String 和 Int类型的公共父类型Any
数组一初始化长度固定
"可变"数组:
插入删除元素:
遍历 Array和ArrayBuffer:
增强for循环 :
数组常见操作:
转换数组:
Array 求平方:
ArrayBuffer求平方:
实现偶数才求平方 :
性能比较差的方式:
优化以后的算法:
首先遍历收集需要保留下来的索引,然后将这些全部移到数据最前面,最后直接截取需要的结果即可。
Map:
创建 Map的四种方式:
增加元素:
移出元素 :
用 yield,for推导式生成新的Map,增强for循环遍历:
不可变集合:
可变集合 :
SortedMap可以自动 对Map的key排序:
如何维护自定义的插入顺序?使用LinkedHashMap
HashMap:
LinkedHashMap:
Tuple相当于元祖,里面不一定是一对值,可能是三个、四个 。
zip拉链组合:
遍历数组,这个数组的每个元素都是一个Tuple:
面向对象:
对象私有 隔离级别最高。
java中需要9行代码。
构造函数:
辅助构造函数相当于重载,可调用 主构造函数,辅助构造函数之间可以互相调用。
没有任何方法使用到传入的参数值,则不会创建任何field:
通常只共享一份的“东西”,会放到object中。
object和class很相似,可以放一些扩展 ,可以放方法等等,唯一不同的是它不能 定义不带参数的constructor。
它只有不接受参数的默认的constructor。
伴生类和伴生对象可以互相访问私有的变量是一大特点。
直接访问是访问不到的,但在伴生对象中才可以访问到。
继承抽象类,实现抽象方法:
继承:
反例:
使用protected则可以直接访问 父类变量:
只能在 当前 实例访问protect[this]
匿名内部类:
抽象类:
不可以直接实现person实例
模式匹配进行类型 的判断:
Trait 特质:
第一个是父trait,注意不是抽象方法。
调用多个trait里实现的方法
会从右至左调用,解决了java中会出现多继承的问题(之所以java不可以多继承是因为继承的类 可能会有 多个相同的方法)
返回为false的情况:
返回为true的情况:
因为trait的 构造是在它自己之前的,而这个trait的 抽象 field去tostring当然初始化就报错了。
创建实例的时候,在所有东西初始化之前,提前先重写了msg,对像能正常的初始化。
另一种写法:
在sayHello()之前重写了抽象field。
另一种方法是使用 lazy value
应该对lazy值进行初始化:
函数式编程:
匿名函数:
高阶函数第一种:
函数体里是调用的传入的函数。
Array的map也是一个高阶函数,将数组的元素传入map,每个元素取平方值。
高阶函数第二种:
接收不同的msg,返回一个新的函数,每一个新的函数的msg是不同的。返回类型是函数的函数。
greetingFuncHello和grettingFuncHi创建了不同的函数返回。
闭包:
接收不同的msg,返回一个新的函数,每一个新的函数的msg是不同的。返回类型是函数的函数。
greetingFuncHello和grettingFuncHi创建了不同的函数返回。
注意两次调用getGreetingFunc函数,传入的msg是不同的,也创建了不同 的函数返回,其中的msg是局部变量,但是在getGreetingFunc函数执行完以后,这个变量依然存在,也就是返回的两个函数里面 (greetingFuncHello和grettingFuncHi),你反复调用,这个msg一直存在,按常理msg只能在getGreetingFunc函数作用域里使用。但是现在超出了这个作用域却还在使用,msg这种情况就是闭包。
scala实现闭包的方式就是给每一个函数创建 一个函数对象,在函数对象里面把msg作为它的实体变量,以此让msg脱离原先的局部变量的作用域,以此实现闭包。
SAM转换:
上图:接收参数直接转换成Listener
Currying函数 :
return:
函数式编程之集团操作:
LinkedHashSet
统计多个文本内的单词总数:
统计多个文件内的单词总数:
test01.txt
test02.txt
模式匹配:
Array:
List:
学校门禁案例:
类型参数(类似java中的泛型):
上边界Bounds:
进行了上边界的界定不再报错:
因为worker跟person类不是父类子类关系,所以报错:
下边界Bounds:
上下边界Bounds:
注意:上边界限定类型时用的是左尖括号和冒号,
上下边界限定界限时用的是左尖括号和百分号。
隐式转换:将dog类隐式转换为person类。
Context Bounds:
使用scala内置的比较器比较大小:
蔬菜类也打包成功:
协变:
逆变:
注意:协变和逆变是为了 让函数顺利进行。
Array[_] 下划线相当于占位符。