1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
object
Basic
extends
App
{
/*
class WordCount
{
// Java
public static void main(String[] args)
{
String tx = "Good morning !It is really my honor to have this opportunity is for a interview,I hope i can make is a good performance today";
Map<String, Integer> count = new HashMap<String, Integer>();
for (String word : tx.split(" ")) {
int number = count.containsKey(word) ? count.get(word) : 0;
count.put(word, number + 1);
}
}
}
*/
/*
<?PHP
// PHP
$text = "Good morning !It is really my honor to have this opportunity is for a interview,I hope i can make is a good performance today";
foreach (explode(" ", $text) as $w) $count[$w] += 1;
?>
*/
/*
# python
text = "Good morning !It is really my honor to have this opportunity is for a interview,I hope i can make is a good performance today"
count = {}
for word in text.split(" "): count[word] = count[word] + 1 if word in count else 1
*/
/*
// Scala
object WordCount extends App
{
val text = "Good morning !It is really my honor to have this opportunity is for a interview,I hope i can make is a good performance today"
(Map[String, Int]() /: text.split(" ")) { (i, j) => i(j) = i.getOrElse(j, 0) + 1; i }
}
*/
// 基本类型
//Byte, Char, Short, Int, Long, Float, Double, Boolean
1
.toChar;
"10"
.toInt
// 变量 不变量 其中var 与 val 的区别在于,var 是变量,以后的值还可以改变, val的值只能在声明的时候赋值,但是val不是常量,只能说是不变量或只读变量
val
answer
=
8
*
5
+
2
var
conter
=
0
val
greeting
:
String
=
"Hello"
// 打印
print(
"Answer: "
)
println(
"53"
)
// 高级For循环
1
to
10
// Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
1
until
10
// Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
for
(i <-
1
to
10
) print(
_
)
for
(i <-
1
to
10
;
if
i
%
2
==
0
) print(
_
)
for
(i <-
1
to
3
; j <-
1
to
3
if
i !
=
j) print((
10
* i + j) +
" "
)
// 12 13 21 23 31 32
for
(i <-
1
to
3
; a
=
4
- i; j <- a to
3
) print((
10
* i + j) +
" "
)
// 13 22 23 31 32 33
// 匹配模式
val
num
=
10
num
match
{
case
x
if
x
==
1
=
> println(
"one, a lonely number"
)
case
x
if
(x
==
2
|| x
==
3
)
=
> println(x)
case
_
=
> println(
"some other value"
)
}
val
m
=
num
match
{
case
x
if
x
==
10
=
>
5
case
"4"
=
>
6
case
_
=
>
9
}
// 函数
// 函数定义:
def
方法名(参数名
:
参数类型)
:
返回类型
=
{
//block内最后一一行行为返回值
}
当返回值为Unit时可以定义为
:
def
方法名(参数名
:
参数类型)
{
//code
}
// 在Scala中,你需要为函数参数指定类型签名。
def
addOne(m
:
Int)
:
Int
=
{
m +
1
}
addOne(
2
)
// 3
// 如果函数不带参数,你可以不写括号。
def
three()
=
1
+
2
def
three
=
1
+
2
three
// 3
// 匿名函数
// 你可以传递匿名函数,或将其保存成不变量。
val
addTwo
=
(x
:
Int)
=
> x +
1
addTwo(
1
)
// 2
{ i
:
Int
=
>
println(
"hello world"
)
i *
2
}
// 可变长度参数
// 这是一个特殊的语法,可以向方法传入任意多个同类型的参数。例如要在多个字符串上执行String的capitalize函数,可以这样写:
def
capitalizeAll(args
:
String*)
=
{
args.map { arg
=
>
arg.capitalize
}
}
capitalizeAll(
"rarity"
,
"applejack"
)
// ArrayBuffer(Rarity, Applejack)
// 偏函数
trait
PartialFunction[A, B]
extends
(A)
=
> B
// 偏函数recieve在akka的Actor起到关键作用。例如:
case
object
Greet
case
class
WhoToGreet(who
:
String)
case
class
Greeting(message
:
String)
class
Greeter
extends
Actor
{
var
greeting
=
""
def
receive
:
Actor.Receive
=
{
case
WhoToGreet(who)
=
> greeting
=
s
"hello, $who"
case
Greet
=
> sender ! Greeting(greeting)
}
}
//而Actor.Receive的定义为:type Receive = PartialFunction[Any, Unit]
//偏函数receive以case object, case class为message Domain,返回Unit (即receive不会返回一个普通类型(如:String, Int等)值)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
object
Collection
extends
App
{
// Map List Tuple Array Set Queue Stack
// Array
// 10个正数的数组,所有元素初始化为0
val
nums
=
new
Array[Int](
10
);
val
array
=
Array(
"Hello"
,
"World"
)
// 变长数组
import
scala.collection.mutable.ArrayBuffer
val
b
=
ArrayBuffer[Int]()
b +
=
1
b +
=
(
1
,
2
,
3
)
b ++
=
Array(
1
,
2
,
3
)
b(
0
)
// 取值
// 迭代
for
(e <- b) println(e)
b.foreach(e
=
> println(e))
b.foreach(println(
_
))
b foreach println
// Map
import
scala.collection.mutable.Map
val
source
=
Map(
"Alice"
->
10
,
"Bob"
->
3
,
"Cindy"
->
5
)
val
jMap
:
HashMap[String, Int]
=
new
HashMap[String, Int]()
val
item
=
source(
"Bob"
)
source(
"Fred"
)
=
7
source +
=
(
"Bob"
->
10
,
"Fred"
->
7
)
for
((k, v) <- source) println(s
"$k => $v"
)
// Tuple
val
tuple
=
(
1
,
3
,
14
,
"Fred"
)
// Tuple3[Int, Doubel, java.lang.String]
println(s
"$tuple._1, $tuple._2, $tuple._3"
)
// 模式匹配获取元祖
val
(first, second, third)
=
tuple
// List
import
scala.collection.mutable.ListBuffer
val
list
=
ListBuffer[Int]();
list +
=
1
list +
=
2
list ++
=
List(
3
,
4
,
5
)
list(
0
) + list(
1
) + list(
2
)
// method [foreach filter map reduce sum max min count partition zip mkString]
val
names
=
List(
"Peter"
,
"Paul"
,
"Mary"
)
val
numbers
=
List(
1
,
2
,
3
,
4
)
// filter 移除任何使得传入的函数返回false的元素。返回Boolean类型的函数一般都称为断言函数。
names.filter(
_
.length <
5
)
// List("Paul", "Mary")
numbers.filter((i
:
Int)
=
> i
%
2
==
0
)
// List(2, 4)
def
isEven(i
:
Int)
:
Boolean
=
i
%
2
==
0
numbers.filter(isEven
_
)
// List(2, 4)
// map 在列表中的每个元素上计算一个函数,并且返回一个包含相同数目元素的列表。
names.map(
_
.toUpperCase)
// List("PETER", "PAUL", "MARY")
numbers.map((i
:
Int)
=
> i *
2
)
// List(2, 4, 6, 8)
// foreach和map相似,只不过它没有返回值,foreach只要是为了对参数进行作用。
numbers.foreach((i
:
Int)
=
> i *
2
)
//
// reduce reduceLeft接受一个接受两个参数的函数,reduceLeft会依次把前一次得到的结果和下一个列表元素传递给函数,最后得到一个单个元素
List(
2
,
4
,
6
).reduceLeft(
_
+
_
)
// 12 相当于: ((2 + 4) + 6)
List(
1
,
4
,
9
,
6
,
7
).reduceLeft( (x,y)
=
>
if
(x>y) x
else
y )
// 9 ((((1 max 4) max 9) max 6) max 7)
// sum max min count
numbers.sum
// 10
numbers.max
// 4
numbers.min
// 1
numbers.count(
_
>
0
)
// 4
// partition
val
numList
=
List(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
)
numList.partition(
_
%
2
==
0
)
// (List(2, 4, 6, 8, 10), List(1, 3, 5, 7, 9))
// zip
List(
1
,
2
,
3
).zip(List(
"a"
,
"b"
,
"c"
))
// List((1,a), (2,b), (3,c))
// mkString
names.mkString(
", "
)
// Peter, Paul, Mary
names.mkString(
"<"
,
", "
,
">"
)
// <Peter, Paul, Mary>
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
object
Example
extends
App
{
// 快速排序
object
QuickSort
{
def
main(args
:
Array[String])
:
Unit
=
{
var
arrays
=
Array(
123
,
343
,
5435
,
23
,
3213
);
println(
"排序前的结果"
);
arrays.foreach(println)
arrays
=
sort(arrays);
println(
"排序后的结果"
);
arrays.foreach(println)
}
def
sort(xs
:
Array[Int])
:
Array[Int]
=
{
if
(xs.length <
=
1
)
xs;
else
{
val
pivot
=
xs(xs.length /
2
);
Array.concat(
sort(xs filter (pivot >
_
)), xs filter (pivot
==
_
), sort(xs filter (pivot <
_
))
)
}
}
}
// 使用蒙特卡洛方法计算Pi值
object
SparkPi
{
def
main(args
:
Array[String])
{
val
conf
=
new
SparkConf().setAppName(
"Spark Pi"
)
val
spark
=
new
SparkContext(conf)
val
slices
=
if
(args.length >
0
) args(
0
).toInt
else
2
val
n
=
100000
* slices
val
count
=
spark.parallelize(
1
to n, slices).map { i
=
>
val
x
=
random *
2
-
1
val
y
=
random *
2
-
1
if
(x * x + y * y <
1
)
1
else
0
}.reduce(
_
+
_
)
println(
"Pi is roughly "
+
4.0
* count / n)
spark.stop()
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
object
Object
extends
App
{
// 类
class
Calculator
{
val
brand
:
String
=
"HP"
@
BeanProperty
var
color
:
String
=
_
def
add(m
:
Int, n
:
Int)
:
Int
=
m + n
}
val
calc
=
new
Calculator
calc.add(
1
,
2
)
// 3
calc.brand
// "HP"
calc.brand
=
"PH"
// 在Scala中getter和setter方法并非被命名为getXxx和setXxx,不过他们的意思是相同的
/* Java
public class Person
{
private int age;
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
*/
// 继承
class
ScientificCalculator(brand
:
String)
extends
Calculator(brand)
{
def
log(m
:
Double, base
:
Double)
=
math.log(m) / math.log(base)
}
// 重载 & 重写
class
EvenMoreScientificCalculator(brand
:
String)
extends
ScientificCalculator(brand)
{
def
log(m
:
Int)
:
Double
=
log(m, math.exp(
1
))
override
def
add(x
:
Int, y
:
Int)
=
x + y
}
// 抽象类 你可以定义一个抽象类,抽象类可以定义一些方法,但是不需要实现它们。相反,继承抽象类的子类需要实现这些方法。抽象类是不能被实例化的。
abstract
class
Shape
{
def
getArea()
:
Int
// subclass should define this
}
class
Circle(r
:
Int)
extends
Shape
{
def
getArea()
:
Int
=
{ r * r *
3
}
}
// 不能实例化一个抽象类
val
s
=
new
Shape
// error: class Shape is abstract; cannot be instantiated val s = new Shape
val
c
=
new
Circle(
2
)
// Traits traints表示一系列可以扩展或者混入到你的类里的成员和行为。
trait
Car
{
val
brand
:
String
}
trait
Shiny
{
val
shineRefraction
:
Int
}
class
BMW
extends
Car
{
val
brand
=
"BMW"
}
// 通过with关键字,一个类可以扩展多个traint:
class
BMW
extends
Car
with
Shiny
{
val
brand
=
"BMW"
val
shineRefraction
=
12
}
/*
什么时候你需要使用Trait代替抽象类? 如果你想定义一个类似接口的类型,
那么你很难在trait和抽象类之间做出选择。它们都可以让你定义一个具有某些行为的类型,
然后要求扩展者去实习其他的行为。下面是一些经验法则:
优先使用traint。一个类可以扩展多个traint,但是只能扩展一个抽象类。
如果你需要在构造类的时候传入参数的话,那就是用抽象类。抽象类的构造器可以传入参数,trait则不能。
例如,你不能这样写trait t(i:Int) {} ;参数i是非法的。
*/
// 伴生类
class
Pizza (
var
crustType
:
String)
{
override
def
toString
=
"Crust type is "
+ crustType
}
object
Pizza
{
val
CRUST
_
TYPE
_
THIN
=
"thin"
val
CRUST
_
TYPE
_
THICK
=
"thick"
def
getFoo
=
"Foo"
}
var
p
=
new
Pizza(Pizza.CRUST
_
TYPE
_
THICK)
}
|