Programming in scala学习笔记(二)Next steps in scala

来源:互联网 发布:网络舆论的影响答案 编辑:程序博客网 时间:2024/05/29 14:14

1 声明一个数组



Java的string数组声明如下:

String[] greetStrings = new String()[4];

数组索引跟java和c++/c语言不一样的是不用”[ ]“,用“( )”。

也可以用比较繁琐的方式声明数组:


greetStrings是val常量,只能指向同一个Array对象,但是,greetStrings(0-2)的值是可变的。



2. 关于数组为什么不用”[ ]”,用“( )”

Array是类,任何定义的数组都是Array的对象。调取数据的某一个元素需要调用apply()方法,scala会自动将greetStrings(0)翻译成greetStrings.apply(0)。

greetStrings(0) = "Hello"翻译为:greetStrings.update(0, "Hello")

第1小节的代码可以翻译为:


注意上面for循环中的写法,很好玩,因为to也是个函数,由0初始化的实例调用。具体请看第3小节。

更简洁的方式:


上面实际调用了一个工厂方法,根据输入的类型返回相应Array类型并初始化。

 

3.在scala中,所有的操作符都是函数

下图为1+2的函数调用:

 




4.scala的List

Array中的元素是可变的,List是不可变的(java中的list是可变的)。

 

===用::连接元素和List===

 

===用:::连接两个List,赋值给新的List===

 

 ===Nil为空List===

 

===List的常用方法===

序号

函数名(以thrill:List[String]为例)

说明

1

thrill.count(s => s.length == 4)

返回长度等于4的元素的个数

2

thrill.drop(2)

返回去除前两个元素的List

3

thrill.dropRight(2)

返回去除最后两个元素的List

4

thrill.exists(s => s == "until")

判断是否满足条件,返回true or false

5

thrill.filter(s => s.length == 4)

返回符合条件的所有元素组成的List

6

thrill.forall(s =>s.endsWith("1"))

对于所有的数据,是否满足给定的条件

7

thrill.foreach(s => print(s))

遍历List中的元素,s为function literal参数

8

thrill.head

返回第一个

9

thrill.last

返回最后一个

10

thrill.init

类似thrill.dropRight(1)

11

thrill.tail

 

12

thrill.map(s => s + "y")

对List中的每个元素进行处理,在每个元素后面加上字符串“y”。

13

thrill.mkString(", ")

将所有元素以字符串形式连接起来,用“,”分隔,返回一个总的字符串

14

thrill.remove(s => s.length == 4)

移除满足条件的元素

15

thrill.reverse

List中的元素反转

16

thrill.sort(

(s,t) => s.charAt(0).toLower <

t.charAt(0).toLower

)

按照function literal进行排序,小写字幕序,由小到大

17

thrill.reduce(

(s, t) =>{

 if (s.length <t.length)  t  else  s

)

处理列表的每个元素并返回一个值,比如求list中的最大值,可以在reduce中传入一个两两比较大小的function literal,最后返回一个最大值,reduce遍历list的方向没有保证,reduceLeftreduceRight规定了方向

 

Thrill.reduceLeft

从左到右搞

 

Thrill.reduceRight

从右到左搞

 

以上的函数不仅可以用于List,也应该可以用于Array,在Array上尝试了一个map函数如下:

 



5. 列表、数组的map函数

===的map函数===

Map用于对每个元素利用传入的函数做映射处理。

scala> list1

res3: List[Int] =List(0,1,2,3,4,5,6,7,8,9,10)

 

scala> list1.map(x=>x*x)

res4: List[Int] =List(0,1,4,9,16,25,36,49,64,81,100)

 

===flatMap函数===

FlatMap可以处理列表的列表,也可以处理列表,最终只输出一个综合的列表。


如上面截图所示,用map(x => 1 to x),返回的List里面包含若干Range,而用flatMap会合并成一个List。下面的例子是对元素为Range的List进行处理的截图:


以下为元素为List的List的flatMap处理:


用map做处理的时候,返回结果不能将多个子List合并:

 


6. zip、zipall、zipWithIndex函数

Zip的主要功能是合并两个列表或者数组,只是元素和元素之间的合并。

scala> val list ="Hello.World".toCharArray

list:Array[Char] =Array(H, e, l, l, o, ., W, o, r, l, d)

 

scala> val list1 = 1 to20toList

list1: List[Int] =List(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)

 

scala> list.zip(list1)

res30: Array[(Char, Int)] =Array((H,1),(e,2), (l,3), (l,4),(o,5), (.,6), (W,7),(o,8), (r,9), (l,10),(d,11))

 

scala> list1.zip(list)

res31: List[(Int, Char)] =List((1,H),(2,e), (3,l), (4,l),(5,o), (6,.), (7,W),(8,o), (9,r), (10,l),(11,d))

返回的列表长度取决于较短的列表,只要有一个列表到达了末尾 zip 函数就停止了。我们可以使用 zipAll 函数来对较长列表的剩余元素进行处理:

scala> list.zipAll(list1,'a','1')

res33: Array[(Char, AnyVal)] =Array((H,1), (e,2), (l,3), (l,4), (o,5), (.,6), (W,7), (o,8), (r,9), (l,10), (d,11), (a,12), (a,13), (a,14), (a,15), (a,16), (a,17), (a,18), (a,19), (a,20))

(译者注:最后一个参数为1,让返回类型是Array[(Char,Int)]对于这个例子更好点

如果字母的列表比较短,那么用 'a' 来补充,反之用1来补充

最后一个要介绍的zip 函数是 zipWithIndex 。就像他的名字一样,元素的下标(从0开始)会被增加进去:

scala> list.zipWithIndex
res36: Array[(Char, Int)] = Array((H,0), (e,1), (l,2), (l,3), (o,4), (.,5), (W,6), (o,7), (r,8), (l,9), (d,10))  



7. reduce、reduceLeft、reduceRight函数

使用 reduce 我们可以处理列表的每个元素并返回一个值,就像个滑动窗口一样。通过使用 reduceLeft  reduceRight 我们可以强制处理元素的方向。(使用 reduce 方向是不被保证的)。

scala> list1

res51: List[Int] = List(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)

 

scala> val sum = (x:Int, y:Int) => {print(x,y) ; x + y}

sum: (Int, Int) => Int = <function2>

 

scala>list1.reduce(sum)

(1,2) (3,3) (6,4) (10,5) (15,6) (21,7)(28,8) (36,9) (45,10) (55,11) (66,12) (78,13) (91,14) (105,15) (120,16)(136,17) (153,18) (171,19) (190,20)

res52: Int = 210

 

scala>list1.reduceLeft(sum)

(1,2) (3,3) (6,4) (10,5) (15,6) (21,7)(28,8) (36,9) (45,10) (55,11) (66,12) (78,13) (91,14) (105,15) (120,16)(136,17) (153,18) (171,19) (190,20)

res53: Int = 210

 

scala>list1.reduceRight(sum)

(19,20) (18,39) (17,57) (16,74) (15,90)(14,105) (13,119) (12,132) (11,144) (10,155) (9,165) (8,174) (7,182) (6,189) (5,195)(4,200) (3,204) (2,207) (1,209)

res54: Int = 210

 

 

8. scala的元组tuples

 

元组中的元素也是不可变的(Array中元素可变,List不可变),但是可以允许有多种不同类型的元素。

元组的定义和访问方式如下所示:


元组中的元素索引从1开始,而且访问用”._X”访问。这点比较独特。

 


9. sets和maps(集合和映射)

 

===定义和操作set的语句===

 

===Set的继承关系===

Scala有一个基Trait,然后分别有两个子trait,一个是可变的(指向的对象可变),一个是不可变的。默认情况下都是不可变的。这样,在用+和+=语句的时候,都会重新生成一个新的Set。可变的set在使用的时候需要前面加上:import scala.collection.mutable.Set

 

===Hashset的调用跟set一样===

 

===Map的使用方式===

===函数“->”返回key-value的tuple===

上面是先声明然后初始化,也可以这样定义:

 

 

===几种函数的定义,遍历array中的参数输出===

第一种,最笨的方法,用var变量:

第二种,用for循环:


第三种,用foreach函数:

上面的foreach是下面的简写:

args.foreach((arg:String) => println(arg))

如果传入的function literal 函数体仅有一个参数和一个声明,整个function Literal可以仅仅保留函数体。

 


10 从文件中读取行内容

 

用类scala.io.Source,fromFile方法应该是返回一个文件对象,然后用getLines方法遍历每行数据。

 


11 这几个符号的作用“->”“<-”“=>”“::””:::”

符号”->”: 返回key-value的tuple对,可以给map赋值。

符号“<-”: 遍历集合中的元素。

符号“=>”: function literal中用于指向函数体。

符号“::”: 连接元素和List对象。

符号”:::”: 连接两个List对象。

 

1 0