您的位置:首页 > 其它

Scala学习(七)练习

2015-06-30 08:16 295 查看
控制结构和函数

1. 编写示例程序,展示为什么

package com.horstmann.impatient

不同于

package com

package horstmann

package impatient

描述: 区别是后者的上层包也可见,而串写的只有当前包范围可见

程序代码: b.scala

package com{

package horstmann{

object A{

def hi=println("I am A")

}

package impatient{

object B extends App{

def hi=A.hi

hi

}

}

}

}

运行结果:


E:\Test>scalac b.scala

E:\Test>scala com.horstmann.impatient.B

I am A

E:\Test>


程序代码: c.scala


package com.horstmann.impatient{

object C extends App{

B.hi

A.hi

}

}


运行结果:


E:\Test>scalac c.scala

c.scala:4: error: not found: value A

A.hi

^

one error found

E:\Test>


编译时找不到A,说明串联声明时不包含上级声明

程序代码: d.scala


E:\Test>scalac d.scala

E:\Test>scala com.horstmann.impatient.C

I am A

I am A

E:\Test>


2. 编写一段让你的Scala朋友们感到困惑的代码,使用一个不在顶部的com包

程序代码: a1.scala


package com {

package horstmann {

package com {

package horstmann {

object A {

def hi = println("I am the Ghost A")

}

}

}

}

}


程序代码: a2.scala


package com {

package horstmann {

object A {

def hi =println("I am A")

}

package impatient {

object B extends App {

def hi = com.horstmann.A.hi

hi

}

}

}

}


先编译a2.scala再编译a1.scala运行结果如下:


E:\Test>scalac a2.scala

E:\Test>scalac a1.scala

E:\Test>scala com.horstmann.impatient.B

I am A

E:\Test>


先编译a1.scala再编译a1.scala运行结果如下:


E:\Test>scalac a1.scala

E:\Test>scalac a2.scala

E:\Test>scala com.horstmann.impatient.B

I am the Ghost A

E:\Test>


3. 编写一个包random,加入函数nextlnt(): Int、nextDouble(): Double和setSeed(seed : Int): Unit。生成随机数的算法采用线性同余生成器:

后值 =(前值×a+b)mod 2n

其中,a = 1664525,b =1013904223,n =32,前值的初始值为seed。

程序代码:

package random{

object Random {

private val a = 1664525

private val b = 1013904223

private val n = 32

private var seed=0

private var follow:BigInt=0

private var previous:BigInt=0

def nextInt():Int={

follow=(previous*a+b)%BigInt(math.pow(2, n).toLong)

previous=follow

(follow%Int.MaxValue).intValue()

}

def nextDouble():Double={

nextInt.toDouble

}

def setSeed(newSeed:Int){

seed=newSeed

previous=seed

}

}

}

object Test extends App{

var r =random.Random

r.setSeed(args(0).toInt)

for(i <- 1 to 10) println(r.nextInt())

for(i <- 1 to 10) println(r.nextDouble())

}

运行结果:


E:\Test>scalac Random.scala

E:\Test>scala Test 0

1013904223

1196435762

1372387050

720982837

1649599747

523159175

1476291629

601448361

33406696

351317787

1.27442629E9

1.020336477E9

4.8889166E8

1.654060783E9

2.8987765E7

6.3353937E7

8.92205936E8

1.338634754E9

1.649346937E9

6.21388933E8

E:\Test>


4. 在你看来,Scala的设计者为什么要提供package object法而不是简单地让你将函数和变量添加到包中呢

直接加函数和变量声明到包中,比如com.a.b.c。这样就跟c下面的的class或者object差 了一个层级。他们实际上是c下面的所有类的共同的上级定义。这样一来就没有了封装性。 而实现上来说估计也比较麻烦。

5. private[com] def giveRaise(rate: Double)的含义是什么,有用吗

该函数在com包下可见,可以扩大函数的可见范围

6. 编写一段程序,将Java哈希映射中的所有元素拷贝到Scala哈希映射。用引入语句重命名这两个类

程序代码:

import java.util.{HashMap=>JHashMap}

import scala.collection.mutable.HashMap

object JavaMap {

def transMapValues(javaMap:JHashMap[Any,Any]):HashMap[Any,Any]={

val result=new HashMap[Any,Any]

for(k <- javaMap.keySet().toArray()){

result+=k->javaMap.get(k)

}

result

}

def main(args: Array[String]): Unit = {

val jmap:JHashMap[Any,Any]=new JHashMap[Any,Any]

var smap=new HashMap[Any,Any]

for(i <- 1 to 9)

jmap.put(i,"JavaMap"+i)

smap=transMapValues(jmap)

smap.foreach(println)

}

}

运行结果:


(8,JavaMap8)

(2,JavaMap2)

(5,JavaMap5)

(4,JavaMap4)

(7,JavaMap7)

(1,JavaMap1)

(9,JavaMap9)

(3,JavaMap3)

(6,JavaMap6)


7. 在前一个练习中,将所有引入语句移动到尽可能小的作用域里

描述:import可以放到任何区域,直接放到对象结构体当中,也没有问题

程序代码:

object JavaMap {

import java.util.{HashMap=>JHashMap}

import scala.collection.mutable.HashMap

def transMapValues(javaMap:JHashMap[Any,Any]):HashMap[Any,Any]={

val result=new HashMap[Any,Any]

for(k <- javaMap.keySet().toArray()){

result+=k->javaMap.get(k)

}

result

}

def main(args: Array[String]): Unit = {

val jmap:JHashMap[Any,Any]=new JHashMap[Any,Any]

var smap=new HashMap[Any,Any]

for(i <- 1 to 10)

jmap.put(i,"JavaMap"+i)

smap=transMapValues(jmap)

smap.foreach(println)

}

}

8. 以下代码的作用是什么,这是个好主意吗

import java._

import javax._

引入了java和javax的所有内容。因为Scala会自动覆盖java的同名类,不会有冲突。即使这样,引入过多的包,也会让人很迷惑。况且scala编译就已经够慢的了

9. 编写一段程序,引人java.lang.System类,从user.name系统属性读取用户名,从Console对象读取一个密码,如果密码不是" secret",则在标准错误流中打印一个消息;如果密码是" secret",则在标准输出流中打印一个问候消息。不要使用任其他引入,也不要使用任何限定词,即带句点的那种

程序代码:

object Sys{

import scala.io.StdIn

import java.lang.System._

def main(args: Array[String]): Unit = {

val pass=StdIn.readLine()

if(pass=="secret"){

val name=getProperty("user.name")

out.printf("Greetings,%s!",name)

}else{

err.println("error")

}

}

}

运行结果:


secret

Greetings,hadoop!


10. 除了StringBuilder,还有那些java.lang的成员是被scala包覆盖的

Console,Math, 还有基本类型包装对象,Long,Double,Char,Short等等都被Scala覆盖了。


如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【Sunddenly】。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: