1. 程式人生 > >Scala練習八

Scala練習八

1. 編寫示例程式,展示為什麼

package com.horstmann.impatient

不同於

package com

package horstmann

package impatient

描述: 區別是後者的上層包也可見,而串寫的只有當前包範圍可見

程式程式碼: b.scala

  1. package com{
  2.   package horstmann{
  3.     object A{
  4.       def hi=println("I am A")
  5.     }
  6.     package impatient{
  7.       object B extends App{
  8.         def hi=A.hi
  9.         hi
  10.       }
  11.     }
  12.   }
  13. }

執行結果:

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。

程式程式碼:

  1. package random{
  2.   object Random {
  3.     private val a = 1664525
  4.     private val b = 1013904223
  5.     private val n = 32
  6.     private var seed=0
  7.     private var follow:BigInt=0
  8.     private var previous:BigInt=0
  9.     def nextInt():Int={
  10.       follow=(previous*a+b)%BigInt(math.pow(2, n).toLong)
  11.       previous=follow
  12.       (follow%Int.MaxValue).intValue()
  13.     }
  14.     def nextDouble():Double={
  15.       nextInt.toDouble
  16.     }
  17.     def setSeed(newSeed:Int){
  18.       seed=newSeed
  19.       previous=seed
  20.     }
  21.   }
  22. }
  23. object Test extends App{
  24.   var r =random.Random
  25.   r.setSeed(args(0).toInt)
  26.   for(i <- 1 to 10) println(r.nextInt())
  27.   for(i <- 1 to 10) println(r.nextDouble())
  28. }

執行結果:

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雜湊對映。用引入語句重新命名這兩個類

程式程式碼:

  1. import java.util.{HashMap=>JHashMap}
  2. import scala.collection.mutable.HashMap
  3. object JavaMap {
  4.   def transMapValues(javaMap:JHashMap[Any,Any]):HashMap[Any,Any]={
  5.     val result=new HashMap[Any,Any]
  6.     for(k <- javaMap.keySet().toArray()){
  7.       result+=k->javaMap.get(k)
  8.     }
  9.     result
  10.   }
  11.   def main(args: Array[String]): Unit = {
  12.     val jmap:JHashMap[Any,Any]=new JHashMap[Any,Any]
  13.     var smap=new HashMap[Any,Any]
  14.     for(i <- 1 to 9)
  15.       jmap.put(i,"JavaMap"+i)
  16.     smap=transMapValues(jmap)
  17.     smap.foreach(println)
  18.   }
  19. }

執行結果:

(8,JavaMap8)

(2,JavaMap2)

(5,JavaMap5)

(4,JavaMap4)

(7,JavaMap7)

(1,JavaMap1)

(9,JavaMap9)

(3,JavaMap3)

(6,JavaMap6)

7. 在前一個練習中,將所有引入語句移動到儘可能小的作用域裡

描述:import可以放到任何區域,直接放到物件結構體當中,也沒有問題

程式程式碼:

  1. object JavaMap {
  2.   import java.util.{HashMap=>JHashMap}
  3.   import scala.collection.mutable.HashMap
  4.   def transMapValues(javaMap:JHashMap[Any,Any]):HashMap[Any,Any]={
  5.     val result=new HashMap[Any,Any]
  6.     for(k <- javaMap.keySet().toArray()){
  7.       result+=k->javaMap.get(k)
  8.     }
  9.     result
  10.   }
  11.   def main(args: Array[String]): Unit = {
  12.     val jmap:JHashMap[Any,Any]=new JHashMap[Any,Any]
  13.     var smap=new HashMap[Any,Any]
  14.     for(i <- 1 to 10)
  15.       jmap.put(i,"JavaMap"+i)
  16.     smap=transMapValues(jmap)
  17.     smap.foreach(println)
  18.   }
  19. }

8. 以下程式碼的作用是什麼,這是個好主意嗎

import java._

import javax._

引入了java和javax的所有內容。因為Scala會自動覆蓋java的同名類,不會有衝突。即使這樣,引入過多的包,也會讓人很迷惑。況且scala編譯就已經夠慢的了

9. 編寫一段程式,引人java.lang.System類,從user.name系統屬性讀取使用者名稱,從Console物件讀取一個密碼,如果密碼不是secret",則在標準錯誤流中列印一個訊息;如果密碼是secret",則在標準輸出流中列印一個問候訊息。不要使用任其他引入,也不要使用任何限定詞,即帶句點的那種

程式程式碼:

  1. object Sys{
  2.   import scala.io.StdIn
  3.   import java.lang.System._
  4.   def main(args: Array[String]): Unit = {
  5.     val pass=StdIn.readLine()
  6.     if(pass=="secret"){
  7.       val name=getProperty("user.name")
  8.       out.printf("Greetings,%s!",name)
  9.    }else{
  10.      err.println("error")
  11.    }
  12.   }
  13. }

執行結果:

secret

Greetings,hadoop!

10. 除了StringBuilder,還有那些java.lang的成員是被scala包覆蓋的

Console,Math, 還有基本型別包裝物件,Long,Double,Char,Short等等都被Scala覆蓋了。