一、下载资源
1、Scala
我们使用Scala2.10.4来学习Scala,下载链接如下。本站下载资源链接点我
http://www.scala-lang.org/download/2.10.4.html
2、Scala开发工具
Scala开发工具有Eclipse和IDEA可选,Eclipse点我下载。IDEA需要安装Scala插件,点我下载。
二、Scala数据类型
数据类型 | 描述 |
Byte | 8bit的有符号数字,范围在-128 -- 127 |
Short | 16 bit有符号数字,范围在-32768 -- 32767 |
Int | 32 bit 有符号数字,范围 -2147483648 到 2147483647 |
Long | 64 bit 有符号数字,范围-9223372036854775808 到9223372036854775807 |
Float | 32 bit IEEE 754 单精度浮点数 |
Double | 64 bit IEEE 754 双精度浮点数 |
Char | 16 bit Unicode字符. 范围 U+0000 到 U+FFFF |
String | 字符串 |
Boolean | 布尔类型 |
Unit | 表示无值,和其他语言中void等同 |
Null | 空值或者空引用 |
Nothing | 所有其他类型的字类型,表示没有值 |
Any | 所有类型的超类,任何实例都属于Any类型 |
AnyRef | 所有引用类型的超类 |
• scala拥有和java一样的数据类型,和java的数据类型的内存布局完全一致,精度也完全一致。
• 上表中列出的数据类型都是对象,也就是说scala没有java中的原生类型。在scala是可以对数字等基础类型调用方法的。
• 在scala中单行字符串和java中的表达方式完全一样,例如"Hi, OutOfMemory.CN",另外scala中还有类似于python的多行字符串表示方式,用三个双引号表示分隔符。
三、Scala基础语法
3.1 变量声明
• val,常量声明
• var,变量声明
• def,函数声明
举例如下:
• val v1 = 2;//变量,不能重新赋值,函数式语言大量提倡使用val变量,Erlang所有的变量都是val的
• var v2 = 3;//变量,和Java的变量一致
• def v3 = v1 * v2;//只是定义v1*v2表达式的名字,并不求值,在使用的求值
3.1.1 懒加载变量
• lazy val lazyVal = { println("I'm too lazy"); 1 }
• println("after lazyVal")
• val x = lazyVal
打印出:
after lazyVal
I'm too lazy
3.2 Scala函数
3.2.1 Scala基础函数
如下图所示是Scala函数的格式,其中def 是函数定义关键字 max 是函数名, x, y 是参数,参数类型是Int,并且是val即不可变的,最后的 : Int是返回值类型。
上面函数可以简化,首先是return ,Scala中,可以不写return,如果不写return 则自动将最后计算的结果作为返回值,如果没有返回值,则函数的返回类型为Unit,类似于Java和C#中 void 。因此上面函数可以简化为:
def max( x : Int, y : Int) : Int = {
if(x > y) x else y
}
变量可以推断返回类型,所以函数也可以写成如下;
def max( x : Int, y : Int) = {
if(x > y) x else y
}
函数体的花括号也可以简化,进一步简化为如下模式;
def max( x : Int, y : Int) = if(x > y) x else y
如下代码就是Scala一个简单的函数
package com.zjt.test01
object hello2 {
def main(args: Array[String]): Unit = {
var maxValue = max(1, 2);
print(maxValue);
}
def max( x : Int, y : Int) = if(x > y) x else y
}
执行结果如下图所示:
3.2.2 Scala函数默认参数
代码如下,其含义慢慢品味:
package com.zjt.test01
object hello3 {
def sayMyName(name : String = "Jack"){
println(name)
}
def main(args: Array[String]): Unit = {
println("函数sayMyName不传参,使用定义的参数默认值Jack");
sayMyName();
println("函数sayMyName传参,使用传入的参数");
sayMyName("rose");
}
}
执行结果如下:
3.2.3 Scala传多个参数
代码如下,其含义慢慢品味:
package com.zjt.test01
object hello4 {
def sumMoreParameters(elem : Int*) = {
var sum = 0
for(e <- elem){
println(e)
sum += e
}
sum
}
def main(args: Array[String]): Unit = {
println("传两个参数[1,2]")
var a = sumMoreParameters(1, 2);
println("返回值为:" + a)
println("传三个参数[1,2,3]")
a = sumMoreParameters(1, 2, 3);
println("返回值为:" + a)
}
}
执行结果如下:
3.2.4 Scala函数部分参数应用
代码如下,其含义慢慢品味:
package com.zjt.test01
object hello5 {
def add(a:Int,b:Int) = a+b
def add2 = add(_:Int,2)
def main(args: Array[String]): Unit = {
println(add2(1))
}
}
执行结果如下:
3.2.5 Scala函数递归
代码如下,其含义慢慢品味:
package com.zjt.test01
object hello6 {
def fac(n:Int):Int = if( n <= 0) 1 else n*fac(n-1)
def main(args: Array[String]): Unit = {
println(fac(3))
}
}
执行结果如下:
3.2.6 Scala函数柯里化
代码如下,其含义慢慢品味:
package com.zjt.test01
object hello7 {
def mulitply(x:Int)(y:Int) = x*y
def m2 = mulitply(2)_;
def main(args: Array[String]): Unit = {
println(mulitply(2)(2))
println(m2(3))
}
}
执行结果如下:
3.2.7 Scala函数匿名化
代码如下,其含义慢慢品味:
package com.zjt.test01
object hello8 {
// => 匿名函数声明方式
val t = ()=>333 //声明了一个函数对象付给了t
def main(args: Array[String]): Unit = {
print(t())
}
}
执行结果如下:
3.2.8 Scala函数匿名化(应用场景01)
代码如下,其含义慢慢品味:
package com.zjt.test01
object hello9 {
// => 匿名函数声明方式
val t = ()=>333 //声明了一个函数对象付给了t
//c代表传进来的参数.
//:后面是数据类型,其数据类型为匿名函数,说明testfunc02只有如参是没有参数且返回值为Int时才会运行
def testfunc02(c : ()=>Int ) = {
println(c())
1000
}
def main(args: Array[String]): Unit = {
print(testfunc02 { t })
}
}
执行结果如下:
3.2.9 Scala函数匿名化(应用场景02)
代码如下,其含义为(匿名函数作为对数据处理的算法,作为入参传入主函数中,主函数中国获取到具体的数据,使用匿名函数处理数据):
package com.zjt.test01
object hello10 {
// 匿名函数作为参数,其实就是参数名,后面跟上参数类型,然后是表达式
// 数据处理函数中获取到数据,调用匿名函数来处理数据
def testf1(callback : (Int,Int)=>Int )={
println(callback(123,123));
}
// 使用匿名函数声明数据处理的算法
var a1 = (a:Int, b:Int) => {
println(a)
println(b)
a + b;
}
def main(args: Array[String]): Unit = {
var a = 1;
var b = 2;
testf1(a1);
}
}
执行结果如下:
3.2.10 Scala嵌套函数
代码如下,其含义慢慢品味:
package com.zjt.test01
object hello11 {
// 嵌套函数,其实就是def里面套一个def
def add3(x:Int, y:Int ,z:Int) : Int = {
def add2(x:Int, y:Int):Int = {
x + y
}
add2(add2(x,y),z)
}
def main(args: Array[String]): Unit = {
print(add3(1,2,3))
}
}
执行结果如下:
3.2.11 Scala函数打怪
下面展示一段代码,应用到了之前的知识点。大家是否能看懂:
package com.zjt.test01
object hello12 {
// 能否看懂???
def sum(f : Int => Int) : (Int , Int) => Int = {
def sumF(a : Int , b : Int) : Int =
if (a >b ) 0 else f(a) + sumF( a + 1 , b)
sumF
}
def main(args: Array[String]): Unit = {
// 定义一个匿名函数
val a = (a:Int) => {
a
}
// 将匿名函数a传给sum,获取到另一个匿名函数
def sumInts = sum(a)
// 调用sum函数返回的匿名函数
println(sumInts(1,2))
}
}
执行结果如下:
3.3 Scala遍历
3.3.1 Scala遍历(to)
代码如下,在下方代码中展示了两种遍历数字的方法,其含义都是一模一样的。
package com.zjt.test02
object hello01 {
def test() : Unit = {
for(i <- 1.to(100)){
println(i)
}
}
def test02() : Unit = {
// 1 to 100 表示遍历1到100,且包含1和100
for(i <- 1 to 100 ){
println(i)
}
}
def main(args: Array[String]): Unit = {
test()
test02()
}
}
执行结果如下:
3.3.2 Scala遍历(until)
代码如下,在下方展示了until的用法。
package com.zjt.test02
object hello02 {
def test() = {
for(i <- 1 until 100 ){
print(i)
print(",")
if (i % 10 == 0) {
println();
}
}
}
def main(args: Array[String]): Unit = {
test()
}
}
代码执行结果如下:
3.3.3 Scala遍历同时加过滤条件
代码如下,遍历1之100之间且对2取余为1,对5取余大于3的数。
package com.zjt.test02
object hello03 {
def test() = {
for(i <- 1 until 100 if(i % 2 == 1) ; if(i % 5 > 3)){
print(i)
print(",")
if (i % 10 == 0) {
println();
}
}
}
def main(args: Array[String]): Unit = {
test()
}
}
执行结果如下:
3.4 Scala的match用法
代码如下,
package com.zjt.test02
object hello04 {
def testmatch(n:Int)={
n match {
case 1 => {println("111") ;n;}
case 2 => println("2222") ;n;
case _ => println("other"); "test";//default
}
}
def main(args: Array[String]): Unit = {
println(testmatch(2));
}
}
执行结果如下:
3.5 Scala集合
3.5.1 Scala的List集合
代码如下:
package com.zjt.test03
object hello01 {
def main(args: Array[String]): Unit = {
var t = List(1,2,3,5,5)
print(t(3))
}
}
执行结果如下图:
3.5.2 Scala的List集合的map函数用法一
代码如下:
package com.zjt.test03
object hello02 {
// 定义匿名函数作为集合中数据处理的算法
val a = (a:Int) => {
a+2
}
def main(args: Array[String]): Unit = {
// 定义一个List集合作为原始数据
var t = List(1,2,3,5,5)
// 使用集合的map函数,传入匿名函数对集合中元素进行处理
println(t.map(a))
}
}
执行结果如下:
3.5.3 Scala的List集合的map函数用法二
在3.5.2中我们使用List的map函数实现对集合中每个元素加2使用了匿名函数的方法,但是这样写过于繁琐。因此还有一种方式来实现:调用List的map函数,使用_表示集合中的元素:
代码如下:
package com.zjt.test03
object hello03 {
def main(args: Array[String]): Unit = {
// 定义一个List集合作为原始数据
var t = List(1,2,3,5,5)
// 使用集合的map函数,传入匿名函数对集合中元素进行处理
println(t.map(_+2));
}
}
执行结果如下:
3.5.3 Scala的List集合的+:函数用法
我们使用List集合的+:函数来实现给List集合前方追加一个元素的操作,代码如下:
package com.zjt.test03
object hello04 {
// 定义一个List集合作为原始数据
var t = List(1,2,3,5,5)
def main(args: Array[String]): Unit = {
// 使用集合的map函数,传入匿名函数对集合中元素进行处理
println(t.+:("test"));
}
}
执行结果如下:
3.5.4 Scala的List集合前方追加元素
3.5.3中我们使用List集合的+:函数给集合前方追加了一个元素,我们这次再使用::给集合前方追加元素,两者的区别是+:是给原始集合前方追加元素,::是追加后返回一个新集合,不更改原始集合。代码如下:
package com.zjt.test03
object hello05 {
// 定义一个List集合作为原始数据
var t = List(2,2,2)
def main(args: Array[String]): Unit = {
// 使用集合的map函数,传入匿名函数对集合中元素进行处理
val t1 = 1 :: t
println(t1)
println(t)
// 组成新的List t作为一个元素
val t3 = t::6::Nil
println(t3)
}
}
执行结果如下:
3.5.5 Scala的List集合foreach遍历
代码如下:
package com.zjt.test03
object hello06 {
// 定义一个List集合作为原始数据
var t = List(1,2,3)
def main(args: Array[String]): Unit = {
t.foreach { x => {println(x)} }
println("-----------------")
t.foreach { println(_) }
}
}
执行结果如下:
3.5.6 Scala的List集合slice分割集合
代码如下:
package com.zjt.test03
object hello07 {
// 定义一个List集合作为原始数据
var t = List(1,2,3)
def main(args: Array[String]): Unit = {
println(t.slice(0, 2))
}
}
执行结果如下:
3.5.7 Scala遍历List集合
代码如下:
package com.zjt.test03
object hello08 {
// 定义一个List集合作为原始数据
var t = List(1,2,3)
def main(args: Array[String]): Unit = {
for(temp <- t) {
println(temp)
}
println("-----------------------");
for(i <- 0 to t.length-1){
print(i + ":")
println(t(i))
}
}
}
执行结果如下图:
3.5.8 Scala的List./方法
代码如下:
package com.zjt.test03
object hello09 {
// 定义一个List集合作为原始数据
var t = List(1,2,3)
def main(args: Array[String]): Unit = {
println(t./:(100)({
(sum,num)=>print(sum+"--"+num+" ");
sum-num
}));
}
}
执行结果如下:
3.5.9 Scala中List的reduce方法
代码如下:
package com.zjt.test03
object hello10 {
// 定义一个List集合作为原始数据
var t = List(1,2,3)
def main(args: Array[String]): Unit = {
// 调用reduce对集合中元素依次相加(相当于1+2+3)
println(t.reduce(_+_));
// 调用reduce对集合中元素依次相减(相当于1-2-3)
println(t.reduce(_-_));
}
}
执行结果如下:
3.5.10 Scala中List的foldLeft方法
代码如下:
package com.zjt.test03
object hello11 {
// 定义一个List集合作为原始数据
var t = List(1,2,3)
def main(args: Array[String]): Unit = {
println(t.foldLeft(10)((sum,num)=>{print(sum+"--"+num+" ");
num+sum;
}));
}
}
执行结果如下:
3.6 元组
元组定义方法如下,一旦定义,其中的值无法改变。
package com.zjt.test03
object hello12 {
def main(args: Array[String]): Unit = {
var tuple01 = (1,5,6,6);
println(tuple01._1)
println(tuple01._4)
}
}
执行结果如下图
3.7 Map
代码如下:
package com.zjt.test04
object TestMap {
def main(args: Array[String]) {
// 定义一个Map
var m1 = Map[String,Int](("a" , 1), ("b" , 2));
// 打印Map
println(m1);
// 打印Map中key为a的value
println(m1("a"));
// 给Map中新加一个键值对
m1 += ("c" -> 3);
println(m1)
// 遍历Map
m1.foreach(a=>{
println(a+" "+a._1+" "+a._2)
});
// 遍历Map的key
m1.keys.foreach(b=>println(m1(b)));
println(m1)
}
}
执行结果如下: