Scala学习笔记——3

一、随笔

1、scala的每个表达式都是有返回值的
2、scala函数的最后一个表达式就是函数的返回值,scala不建议使用return语句
3、scala访问数组的方式是(),而不是[]
例如:

val a=Array[1,2,3]
println(a(2))

二、while循环

1、最好不要用var索引来枚举数组元素
2、foreach方法
例子:

//使用上面的常量a
a.foreach(arg=>println(arg))
>>1
>>2
>>3
//foreach函数的参数类型也是函数(lambda表达式)
/*如果一个函数只有一个参数并且只包含化为一个表达式,那么你无需明确指明参数,因此可简化为*/
a.foreach(println)
//还可以使用for函数
for(arg<-a)
	println(arg)

三、类型参数化数组

1、 Scala 的一个基本规则,如果一个方法只有一个参数,你可以不用括号和 . 来调用这个方法
例如:

1.to(3)
1 to 3

2、在 Scala 中, 你可以使用 new 来实例化一个类。当你创建一个对象的实例时,你可以使用数值或类型参数。如果使用类型参数,它的作用类似 Java 或 .Net 的 Generic 类型。所不同的是, Scala 使用方括号来指明数据类型参数,而非尖括号。比如:

val greetStrings = new Array[String](3)
greetStrings(0)= "Hello"
greetStrings(1)= ","
greetStrings(2)= "world!\n"
for(i <- 0 to 2)
  print(greetStrings(i))

可以看到 Scala 使用 [] 来为数组指明类型化参数,本例使用 String 类型,数组使用 () 而非 [] 来指明数组的索引。其中的 for 表达式中使用到 0 to 2 ,这个表达式演示了 Scala 的一个基本规则,如果一个方法只有一个参数,你可以不用括号和 . 来调用这个方法。

因此这里的 0 to 2, 其实为 (0).to(2) 调用的为整数类型的 to 方法,to 方法使用一个参数。Scala 中所有的基本数据类型也是对象(和 Java 不同),因此 0 可以有方法(实际上调用的是 RichInt 的方法),这种只有一个参数的方法可以使用操作符的写法(不用 . 和括号),实际上 Scala 中表达式 1+2 ,最终解释为 (1).+(2)+,这也是 Int 的一个方法,和 Java 不同的是,Scala 对方法的名称没有太多的限制,你可以使用符号作为方法的名称。

这里也说明为什么 Scala 中使用 () 来访问数组元素,在 Scala 中,数组和其它普遍的类定义一样,没有什么特别之处,当你在某个值后面使用 () 时,Scala 将其翻译成对应对象的 apply 方法。因此本例中 greetStrings(1) 其实是调用 greetString.apply(1) 方法。这种表达方法不仅仅只限于数组,对于任何对象,如果在其后面使用 () ,都将调用该对象的 apply 方法。同样的如果对某个使用 () 的对象赋值,比如:

greetStrings(0)=“Hello”
Scala 将这种赋值转换为该对象的 update 方法, 也就是 greetStrings.update(0,”hello”) 。因此上面的例子,使用传统的方法调用可以写成:

val greetStrings =new Array[String](3)
greetStrings.update(0,"Hello")
greetStrings.update(1,",")
greetStrings.update(2,"world!\n")
for(i <- 0 to 2)
  print(greetStrings.apply(i))

从这点来说,数组在 Scala 中并不是某种特殊的数据类型,和普通的类没有什么不同。

不过 Scala 还是提供了初始化数组的简单方法,比如上面的例子数组可以使用如下代码:

val greetStrings =Array("Hello",",","World\n")

这里使用 () 其实还是调用 Array 类的关联对象 Array 的 apply 方法,也就是:

val greetStrings =Array.apply("Hello",",","World\n")

四、使用Lists

Scala 也是一个面向函数的编程语言,面向函数的编程语言的一个特点是,调用某个方法不应该有任何副作用,参数一定,调用该方法后,返回一定的结果,而不会去修改程序的其它状态(副作用)。这样做的一个好处是方法和方法之间关联性较小,从而方法变得更可靠和重用性高。使用这个原则也就意味着需要把变量设成不可修改的,这也就避免了多线程访问的互锁问题。

前面介绍的数组,它的元素是可以被修改的。如果需要使用不可以修改的序列,Scala 中提供了 Lists 类。和 Java 的 List 不同,Scala 的 Lists 对象是不可修改的。它被设计用来满足函数编程风格的代码。它有点像 Java 的 String,String 也是不可以修改的,如果需要可以修改的 String 对像,可以使用 StringBuilder 类。

比如下面的代码:

val oneTwo = List(1,2)
val threeFour = List(3,4)
val oneTwoThreeFour=oneTwo ::: threeFour
println (oneTwo + " and " + threeFour + " were not mutated.")
println ("Thus, " + oneTwoThreeFour + " is a new list")

定义了两个 List 对象 oneTwo 和 threeFour ,然后通过 ::: 操作符(其实为 ::: 方法)将两个列表连接起来。实际上由于 List 的不可修改特性,Scala 创建了一个新的 List 对象 oneTwoThreeFour 来保存两个列表连接后的值。

List 也提供了一个 :: 方法用来向 List 中添加一个元素,:: 方法(操作符)是右操作符,也就是使用 :: 右边的对象来调用它的 :: 方法,Scala 中规定所有以 : 开头的操作符都是右操作符,因此如果你自己定义以 : 开头的方法(操作符)也是右操作符。

如下面使用常量创建一个列表:

val oneTwoThree = 1 :: 2 ::3 :: Nil
println(oneTwoThree)

调用空列表对象 Nil 的 :: 方法 也就是:

val oneTwoThree =  Nil.::(3).::(2).::(1)

向列表头添加元素

Scala 的 List 类还定义了其它很多很有用的方法,比如 head、last、length、reverse、tail 等。这里就不一一说明了,具体可以参考 List 的文档。

println(onetwothree.head)
>>1
println(onetwothree.last)
>>3
println(onetwothree.reverse)
>>List(3,2,1)
//reverse:相反
println(onetwothree.tail)
>>List(2,3)

五、使用元组Tuples

Scala中另外一个很有用的容器类为 Tuples ,和 List 不同的是,Tuples 可以包含不同类型的数据,而 List只能包含同类型的数据。Tuples 在方法需要返回多个结果时非常有用。(Tuple 对应到数学的 矢量 的概念)。

一旦定义了一个元组,可以使用 ._ 和 索引 来访问元组的元素(矢量的分量,注意和数组不同的是,元组的索引从1开始)。

val pair=(99,"Luftballons")
println(pair._1)
println(pair._2)

当val v=(v1,v2,…)时,默认v时Tuple
元组的实际类型取决于它的分量的类型,比如上面 pair 的类型实际为 Tuple2[Int,String],而 (‘u’,’r’,”the”,1,4,”me”) 的类型为 Tuple6[Char,Char,String,Int,Int,String] 。

目前 Scala 支持的元组的最大长度为 22 。如果有需要,你可以自己扩展更长的元组。

六、Sets和Maps

Scala Set(集合)是没有重复对象的集合,所有的元素都是唯一的。

Scala 语言的一个设计目标是让程序员可以同时利用面向对象和面向函数的方法编写代码,因此它提供的集合类分成了可以修改的集合类和不可以修改的集合类两大类型。比如 Array总是可以修改内容的,而 List 总是不可以修改内容的。类似的情况,Scala 也提供了两种 Sets 和 Maps 集合类。

比如 Scala API 定义了 Set 的 基Trait 类型 Set (Trait 的概念类似于Java中的 Interface,所不同的是Scala中的 Trait 可以有方法的实现),分两个包定义 Mutable (可变)和 Immutable (不可变),使用同样名称的子 Trait 。下图为 Trait 和类的基础关系:
在这里插入图片描述

使用 Set 的基本方法如下:

var jetSet = Set ("Boeing","Airbus")
jetSet +="Lear"
println(jetSet.contains("Cessna"))

缺省情况 Set 为 Immutable Set,如果你需要使用可修改的集合类( Set 类型),你可以使用全路径来指明 Set ,比如 scala.collection.mutable.Set 。

Scala 提供的另外一个类型为 Map 类型,Map(映射)是一种可迭代的key/value结构,所有的值都可以通过键来获取。 Scala 也提供了 Mutable 和 Immutable 两种 Map 类型,如下图所示。

在这里插入图片描述

Map 的基本用法如下(Map 类似于其它语言中的关联数组,如 PHP )

val romanNumeral = Map ( 1 -> "I" , 2 -> "II",
  3 -> "III", 4 -> "IV", 5 -> "V")
println (romanNumeral(4))

在这里插入图片描述
在这里插入图片描述
Set和Map中的元素类型相同时为该元素类型,不同时为Any

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值