您的位置:首页 > 其它

scala学习六: 数组的使用

2014-08-02 15:22 281 查看
(1)scala中的option的使用:

Scala 提供了一种普通的函数方法,打破了这一僵局。在某些方面,
Option
 类型或
Option[T]
,并不重视描述。它是一个具有两个子类 
Some[T]
 和 
None
 的泛型类,用来表示
“无值” 的可能性,而不需要语言类型系统大费周折地支持这个概念。实际上,使用
Option[T]
 类型可以使问题更加清晰(下一节将用到)。

def simpleOptionTest =
{
val footballTeamsAFCEast =
Map("New England" -> "Patriots",
"New York" -> "Jets",
"Buffalo" -> "Bills",
"Miami" -> "Dolphins",
"Los Angeles" -> null)

println(footballTeamsAFCEast.get("Miami"), Some("Dolphins"))
println()
println(footballTeamsAFCEast.get("Miami").get, "Dolphins")
println()
println(footballTeamsAFCEast.get("Los Angeles"), Some(null))
println()
println(footballTeamsAFCEast.get("Sacramento"), None)
println()
}
结果如下:

(Some(Dolphins),Some(Dolphins))

(Dolphins,Dolphins)

(Some(null),Some(null))

(None,None)


注意,Scala 
Map
 中 
get
 的返回值实际上并不对应于传递的键。相反,它是一个 
Option[T]
 实例,可以是与某个值有关的 
Some()
,也可以是
None
,因此可以很清晰地表示没有在
map 中找到键。如果它可以表示 map 上存在某个键,但是有对应的 null 值,这一点特别重要了。

通常,当处理 
Option[T]
 时,程序员将使用模式匹配,这是一个非常函数化的概念,它允许有效地
“启用” 类型和/或值,更不用说在定义中将值绑定到变量、在 
Some()
 和 
None
 之间切换,以及提取 
Some
 的值(而不需要调用麻烦的 
get()
 方法)。

@Test def optionWithPM =
{
val footballTeamsAFCEast =
Map("New England" -> "Patriots",
"New York" -> "Jets",
"Buffalo" -> "Bills",
"Miami" -> "Dolphins")

def show(value : Option[String]) =
{
<span style="background-color: rgb(192, 192, 192);"> value match
{
case Some(x) => x
case None => "No team found"
}</span>
}
assertEquals(show(footballTeamsAFCEast.get("Miami")), "Dolphins")
}


元组对应与Java中的bean对象(再想想,和c++/c中的结构体也是同一个东西)

什么是元组:一组数据的集合

import java.util.Date

def simpleTuples() =
{
val tedsStartingDateWithScala = Date.parse("3/7/2006")
val tuple = ("Ted", "Scala", tedsStartingDateWithScala)
println(tuple._1, "Ted")
println(<span style="background-color: rgb(192, 192, 192);">tuple._2</span>, "Scala")
println(tuple._3, tedsStartingDateWithScala)
}
从元组中去数据的操作如上标记处

数组的使用:

(1)对数组进行遍历

object ArrayExample1
{
def main(args : Array[String]) : Unit =
{
for (i <- 0 to args.length-1)
{
System.out.println(args(i))
}
}
}

object ArrayTest extendsApplication
{
import org.junit._, Assert._

@Test def testFilter =
{
val programmers = Array(
new Person("Ted", "Neward", 37, 50000,
Array("C++", "Java", "Scala", "Groovy", "C#", "F#", "Ruby")),
new Person("Amanda", "Laucher", 27, 45000,
Array("C#", "F#", "Java", "Scala")),
new Person("Luke", "Hoban", 32, 45000,
Array("C#", "Visual Basic", "F#")),
new Person("Scott", "Davis", 40, 50000,
Array("Java", "Groovy"))
)

// Find all the Scala programmers ...
val scalaProgs =
programmers.filter((p) => p.skills.contains("Scala") )

// Should only be 2
assertEquals(2, scalaProgs.length)

// ... now perform an operation on each programmer in the resulting
// array of Scala programmers (give them a raise, of course!)
//
scalaProgs.foreach((p) => p.salary += 5000)

// Should each be increased by 5000 ...
assertEquals(programmers(0).salary, 50000 + 5000)
assertEquals(programmers(1).salary, 45000 + 5000)

// ... except for our programmers who don't know Scala
assertEquals(programmers(2).salary, 45000)
assertEquals(programmers(3).salary, 50000)
}    testFilter
}

函数式编程提倡不可变对象:如下通过map操作创建出一个新的programmer Array数组

@Test def testFilterAndMap =
{
val programmers = Array(
new Person("Ted", "Neward", 37, 50000,
Array("C++", "Java", "Scala", "C#", "F#", "Ruby")),
new Person("Amanda", "Laucher", 27, 45000,
Array("C#", "F#", "Java", "Scala")),
new Person("Luke", "Hoban", 32, 45000,
Array("C#", "Visual Basic", "F#"))
new Person("Scott", "Davis", 40, 50000,
Array("Java", "Groovy"))
)

// Find all the Scala programmers ...
val scalaProgs =
programmers.filter((p) => p.skills.contains("Scala") )

// Should only be 2
assertEquals(2, scalaProgs.length)

// ... now perform an operation on each programmer in the resulting
// array of Scala programmers (give them a raise, of course!)
//
def raiseTheScalaProgrammer(p : Person) =
{
new Person(p.firstName, p.lastName, p.age,
p.salary + 5000, p.skills)
}
val raisedScalaProgs =
scalaProgs.map(raiseTheScalaProgrammer)

assertEquals(2, raisedScalaProgs.length)
assertEquals(50000 + 5000, raisedScalaProgs(0).salary)
assertEquals(45000 + 5000, raisedScalaProgs(1).salary)
}



函数性列表

class ListTest
{
import org.junit._, Assert._

@Test def simpleList =
{
val myFirstList = List("Ted", "Amanda", "Luke")

assertEquals(myFirstList.isEmpty, false)
assertEquals(myFirstList.head, "Ted")
assertEquals(myFirstList.tail, List("Amanda", "Luke")
assertEquals(myFirstList.last, "Luke")
}
}
注意,构建列表与构建数组十分相似;都类似于构建一个普通对象,不同之处是这里不需要 “new”(这是 “case 类” 的功能,我们将在未来的文章中介绍到)。请进一步注意 
tail
 方法调用的结果
— 结果并不是列表的最后一个元素(通过 
last
 提供),而是除第一个元素以外的其余列表元素。

在列表中进行递归处理:

@Test def recurseList =
{
val myVIPList = List("Ted", "Amanda", "Luke", "Don", "Martin")

def count(VIPs : List[String]): Int =  //声明了返回值的
{
if (VIPs.isEmpty)
0
else
count(VIPs.tail) + 1
}

assertEquals(count(myVIPList), myVIPList.length)
}
不使用list的构造函数而是使用另一种更方便的操作:

@Test def recurseConsedList =
{
val myVIPList = "Ted" :: "Amanda" :: "Luke" :: "Don" :: "Martin" :: Nil

def count(VIPs : List[String]) : Int =
{
if (VIPs.isEmpty)
0
else
count(VIPs.tail) + 1
}

assertEquals(count(myVIPList), myVIPList.length)
}
注意:“::”的规则:

在使用 
::
 方法时要小心
— 它引入了一些很有趣的规则。它的语法在函数语言中非常常见,因此 Scala 的创建者选择支持这种语法,但是要正确、普遍地使用这种语法,必须使用一种比较古怪的规则:任何以冒号结束的 “名称古怪的方法” 都是右关联(right-associative)的,这表示整个表达式从它的最右边的 
Nil
 开始,它正好是一个 
List
。因此,可以将 
::
 认定为一个全局的 
::
 方法,与 
String
 的一个成员方法(本例中使用)相对;这又表示您可以对所有内容构建列表。在使用 
::
 时,最右边的元素必须是一个列表,否则将得到一个错误消息。

当然了,列表也可以与模式匹配结合:

@Test def recurseWithPM =
{
val myVIPList = "Ted" :: "Amanda" :: "Luke" :: "Don" :: "Martin" :: Nil //表示一个空list list[nothing]

def count(VIPs : List[String]) : Int =
{
VIPs match
{
case h :: t => count(t) + 1
case Nil => 0
}
}

assertEquals(count(myVIPList), myVIPList.length)
}
在第一个 
case
 表达式中,将提取列表头部并绑定到变量 h,而其余部分(尾部)则绑定到 t;在本例中,没有对 h 执行任何操作(实际上,更好的方法是指明这个头部永远不会被使用,方法是使用一个通配符 _ 代替 h,这表明它是永远不会使用到的变量的占位符)。但是 t 被递归地传递给 
count
,和前面的示例一样。还要注意,Scala
中的每一个表达式将隐式返回一个值;在本例中,模式匹配表达式的结果是递归调用 
count
+ 1
,当达到列表结尾时,结果为 
0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  scala
相关文章推荐