一、Scala编程语法
1
//1、定义一个方法
2
def method1(x: Int, y: Int): Int = {
3
return x * y
4
}
5
//该方法无输入参数,其实是有返回值,默认的自动匹配。
6
def description = name + " is " + age + " years old with " + prop.toBuffer
7
//无输入参数返回值是Session对象
8
def getSession(): Session ={
9
sessions.remove(0)
10
}
11
12
//2、定义一个函数
13
val method2 = (x: Float, y: Float) => x * y
14
println(method2(3.2f,2.0f))
15
16
//3、往方法中传入函数
17
val func = (x: Int, y: Int) => x * y
18
19
def method1(fun: (Int, Int) => Int): Int = {
20
fun(2,6)*2
21
}
22
//在方法中传入参数,执行函数
23
println(method1(func))
24
}
25
26
//4,Array定长数组,输出toBuffer,ArrayBuffer变长数组,remove,insert
27
val a =new Array[Int](10)
28
println(a.toBuffer)
29
val b =new ArrayBuffer[Int](10)
30
println(b)
31
32
//5,插入与倒序输出
33
val a = ArrayBuffer[Float](2.0f, 3.2f, 4.5f)
34
println(a)
35
a.insert(0, 2.0f)
36
for (i <- (0 until a.length).reverse) {
37
println(a(i))
38
}
39
}
40
41
//6,match 按照数据内容匹配
42
val a = Array[String]("nima","shabi","hehe")
43
val name =a(Random.nextInt(a.length)) //0-3以内的随机数0,1,2
44
name match {
45
case "nima" => println("1,nima")
46
case "shabi" => println("2.shabi")
47
case _ => println("3,hehe") //不是以上默认
48
}
49
//按照数据类型来匹配
50
elem match {
51
case x: Int => println("Int " + x)
52
case y: Double if(y >= 0) => println("Double "+ y)
53
case z: String => println("String " + z)
54
case _ => throw new Exception("not match exception")
55
}
56
57
…………………………列表 List………………………………
58
//7,将某元素插入列表前面
59
a :: list ; a +: list ; lst3 = lst1.::(0) ; lst5 = lst1.+:(0)
60
//将某元素添加到list后面
61
lst6 = lst1 :+ 3
62
//将列表合并:
63
lst8 = lst1 ++: lst0 // lst1在前
64
//将2个list合并成一个新的List
65
lst7 = lst1 ++ lst0
66
//ListBuffer,可变序列
67
listBuffer += .append //追加元素
68
69
…………………………集合 Set…………………………………
70
//8,Set可变,不可变
71
val set1 = new HashSet[Int]()
72
//将元素和set1合并生成一个新的set,原有set不变
73
val set2 = set1 + 4 //添加元素
74
//set中元素不能重复
75
val set3 = set1 ++ Set(5, 6, 7) //连接两个set
76
val set0 = Set(1,3,4) ++ set1
77
println(set0.getClass)
78
79
//HashSet不可变,mutable.HashSet可变 追加 += 等价于add
80
……………………………Map 集合………………………………………
81
//9,Map集合
82
val map1 = new mutable.HashMap[String, Int]()
83
//向map中添加数据
84
map1("spark") = 1
85
map1 += (("hadoop", 2))
86
map1.put("storm", 3)
87
println(map1)
88
//从map中移除元素
89
map1 -= "spark"
90
map1.remove("hadoop")
91
println(map1)
92
93
//10 ,类,对象,继承等等
94
构造器:通过参数来确定执行主构造器还是副构造器
95
class Person(val name: String, val age: Int) {
96
println("执行主构造器")
97
var gender="male"
98
def this(name: String, age: Int, gender: String) {
99
this(name, age)//要首先执行此行
100
println("执行辅构造器1")
101
this.gender=gender
102
}
103
}
104
object test {
105
def main(args: Array[String]): Unit = {
106
val p1 = new Person("shabi", 23,"female") //new一个对象,根据参数匹配构造器
107
println(p1.name+p1.age+p1.gender)
108
}
109
}
110
//伴生对象:在Scala的类中,与类名相同的对象叫做伴生对象。类和伴生对象之间可以相互访问私有的方法和属性
111
//即 ,类里面的方法可以访问对象的私有变量<-->对象里面的方法也可以访问类的私有的方法和属性。就是类和对象之间所有的变量都是可以互访的!
112
class Person(name: String, age: Int) {
113
println("执行主构造器")
114
var id = 1
115
private var gender = "male"
116
def printPerson: Unit = {
117
println(this.id + " " + this.gender + " " + this.name + " " + this.age + " " + Person.a)
118
}
119
}
120
object Person {
121
private var a = "唧唧歪歪"
122
def apply(name: String, age: Int): Person = new Person(name, age)
123
124
def main(args: Array[String]): Unit = {
125
val p1 = Person.apply("曾祥雨",23)//新建对象的建议方法!
126
p1.id = 2
127
p1.gender = "female"
128
p1.printPerson
129
}
130
}
131
//通常我们会在类的伴生对象中定义apply方法,当遇到类名(参数1,...参数n)时apply方法会被调用
132
//新建对象时,用apply来实现
133
134
135
//11、匹配样例类
136
case class SubmitTask(id: String, name: String)
137
case class HeartBeat(time: Long)
138
case object CheckTimeOutTask
139
140
object CaseDemo04 extends App{
141
142
val arr = Array(CheckTimeOutTask, HeartBeat(12333), SubmitTask("0001", "task-0001"))
143
144
arr(Random.nextInt(arr.length)) match {
145
case SubmitTask(id, name) => {println(s"$id, $name")//前面需要加上s, $id直接取id的值}
146
case HeartBeat(time) => {println(time)}
147
case CheckTimeOutTask => {println("check")}
148
}
149
}
150
151
//12,Scala高阶函数,作为值的函数,匿名函数,将方法变为函数,柯里化
152
//作为值的函数
153
val fun1 = (x:Int) => x*x
154
arr.map(fun1)
155
//功能一样,匿名函数如下,省略了函数定义步骤
156
arr.map( (x:Int) = >x*x )
157
//第一种:最直观的方式 (Int) => Int
158
new_list = list.map((x: Int) => x * 3)
159
//第二种:由于map方法知道你会传入一个类型为(Int) => Int的函数,你可以简写
160
new_list = list.map((x) => x * 3)
161
//第三种:对于只有一个参数的函数,你可以省去参数外围的()
162
new_list = list.map(x => x * 3)
163
//第四种:(终极方式)如果参数在=>右侧只出现一次,可以使用_
164
new_list = list.map(_ * 3)
165
new_list.foreach(println(_))
166
var a = Array(1,2,3)
167
a.map(_* 3)
168
169
//将方法变为函数
170
def fun(x: Int): Int ={
171
x*x
172
}
173
val fun2=fun _
174
arr2 = arr.map(fun2)
175
176
//柯里化! 柯里化指的是将原来接受两个参数的方法变成新的接受一个参数的方法的过程
177
def m(x:Int)=(y:Int)=>x*y
178
val func = m(3)
179
val func2=func(5)
180
println(func2)
181
182
//隐式转换
183
import context._
184
//放在门面
185
object context{
186
implicit val b ="yin"//隐士值的对象里,数据类型不能一样
187
// implicit val a="yu"
188
}
189
object ImplicitValue {
190
def sayHi()(implicit name :String="aaa"): Unit ={
191
println(s"hi~$name") //当执行找不到值时,去context内寻找类型一样的
192
}
193
def main(args: Array[String]): Unit = {
194
sayHi()
195
}
196
}
二、RDD算子
1
val conf = new SparkConf().setAppName("WC").setMaster("local")
2
val sc = new SparkContext(conf)
3
4
//textFile会产生两个RDD:HadoopRDD -> MapPartitinsRDD
5
val rdd = sc.textFile("d://a.txt") //逐行读取 a \r a b \r a b c \r a b c d \r a b c d e \r
6
// 产生一个RDD :MapPartitinsRDD
7
val rdd2 = rdd.flatMap(_.split(" ")) //按照空格分开 a a b a b c a b c d a b c d e
8
//产生一个RDD MapPartitionsRDD
9
val rdd3 = rdd2.map((_, 1))//构造 (a,1), (a,1), (b,1), (a,1), (b,1), (c,1), (a,1), (b,1), (c,1), (d,1), (a,1), (b,1), (c,1), (d,1), (e,1)
10
//产生一个RDD ShuffledRDD
11
val rdd4 = rdd3.reduceByKey(_ + _) //按照key执行函数(_+_)相同key的value求和。 (a,5), (b,4), (c,3), (d,2), (e,1)
12
13
//产生一个RDD: mapPartitions
14
//val rdd5 = rdd4.saveAsTextFile("d://b.txt")
15
16
println(rdd4.collect().sortBy(_._1).toBuffer //ArrayBuffer( (a,5), (b,4), (c,3), (d,2), (e,1) ) 将map以buffer形式
17
sc.stop()
18
19
//UserLocation,取出数据返回map
20
val rdd1 = sc.textFile("c://bs_log").map(x => {
21
val arr = x.split(",")
22
val mb = (arr(0),arr(2))
23
val flag = arr(3)
24
var time = arr(1).toLong
25
if (flag == "1") time = -time
26
(mb, time)
27
})
28
29
//找区别 val rdd =rdd1.map(_,1)相比上例这个是直接执行函数,匿名函数而已!!!
30
//join
31
val rdd1.join(rdd) rdd1=(k , v) rdd2=(k , w) join之后返回一个(k,(v,w))
32
33
34
三、Akka.Actor
Worker和Master编程的区别:都是继承了Actor实现方法,也都实现了自己的ip地址和端口号的设置。
区别:Worker的preStart方法连接到了Master
Akka的Actor核心:其实是通过继承Actor实现了若干个可以互相连接的节点。只是要有一个节点来管理其他节点,老大叫Master,其他叫Worker。
这些节点实现的消息处理是谁发给我消息,监听到后我返回给谁
A:对于Master来说,实现一个对外可以连接的IP地址和端口号即可,再就是丰富其匹配的消息的业务逻辑。
B:对于这若干个Worker来说,
①要在preStart()方法中实现链接的Master的IP地址和端口号,并且发送"connect"消息来表明连接。
②要在接收消息的方法中匹配Master连接成功的消息,来表明自己连接到了Master。
③要在实例化自己时,把要连接的Master的IP地址和端口号传入。
④命名为worker
四、Spark编程
1
//设置日志输出内容,
2
LoggerLevels.setStreamingLogLevels()
3
object LoggerLevels extends Logging {
4
def setStreamingLogLevels() {
5
val log4jInitialized = Logger.getRootLogger.getAllAppenders.hasMoreElements
6
if (!log4jInitialized) {
7
logInfo("Setting log level to [WARN] for streaming example." +
8
" To override add a custom log4j.properties to the classpath.")
9
Logger.getRootLogger.setLevel(Level.WARN)
10
}
11
}
12
}
13
//取出数据,返回map
14
val rdd1 = rdd0.reduceByKey(_+_).map(t => {
15
val mobile = t._1._1
16
val lac = t._1._2
17
val time = t._2
18
(lac, (mobile, time))
19
})
20
21
//构造RDD有三种方式:(1)、从集合中创建RDD;(2)、从外部存储创建RDD;(3)、从其他RDD创建。
22
val rdd1 = sc.parallelize(List(("yuihatano", 90, 28, 1), ("angelababy", 90, 27, 2),("JuJingYi", 95, 22, 3)))
23
24
//排序或者调用其他方法示例
25
val rdd2 = rdd1.sortBy(x => Girl(x._2, x._3), false)//排序方法是Girl()
26
27
case class Girl(val faceValue: Int, val age: Int) extends Ordered[Girl] with Serializable {
28
override def compare(that: Girl): Int = {
29
if(this.faceValue == that.faceValue) {
30
that.age - this.age
31
} else {
32
this.faceValue - that.faceValue
33
}
34
}
35
}
36
//partitionBy
37
val ints = rdd3.map(_._1).distinct().collect()
38
val hostPartitioner = new HostParitioner(ints) //ints确定并发量// val rdd4 = rdd3.partitionBy(new HashPartitioner(ints.length))
39
val rdd4 = rdd3.partitionBy(hostPartitioner).mapPartitions(it => {
40
it.toList.sortBy(_._2._2).reverse.take(2).iterator
41
})a
42
43