Scala-Numbers


Scala之Numbers

一、前言

  前面已經學習了Scala中的String,接着學習Scala的Numbers。

二、Numbers

  在Scala中,所有的數字類型,如Byte,Char,Double,Float,Int,Long,Short都是對象,這七種數字類型繼承AnyVal特質,這七種數字類型與其在Java中有相同的范圍,而Unit和Boolean則被認為是非數字值類型,Boolean有false和true兩個值,你可以獲取到各個數字類型的最值。

  

  復雜的數字和日期

  如果需要更強大的數類,可以使用spirescalalab

  如果需要更強大的日期類,可以使用Joda Timenscala-time

  2.1 從字符串中解析數字

  1. 問題

  你想要將字符串類型轉化為數字類型。

  2. 解決方案

  使用String的to*方法即可將String轉化為相應的數字。

  

  當無法進行轉化時,to*方法可能會拋出NumberFormatException異常。

  

  可以直接使用字符串來創建BigInt和BigDecimal實例(也可能會拋出異常)

  

  處理基和基數

  如果在計算時不以10為基(十進制)進行計算,而要使用其他進制,此時Int類的toInt方法不允許傳入基和基數,此時需要使用parseInt方法,parseInt可將字符串轉化為在指定進制下的值

  

  也可以使用隱式轉化來完成上述的功能

  

  3. 討論

  由於在Scala中沒有受檢查異常,因此你不需要在方法中聲明throws NumberFormatException。但是為了使調用者明白該方法可能會拋出異常,你可以使用throws注解 

@throws(classOf[NumberFormatException])
def toInt(s: String) = s.toInt

  更通常而言,在Scala中使用Option/None/Some進行模式匹配來處理  

復制代碼
def toInt(s: String):Option[Int] = {
    try {
        Some(s.toInt)
    } catch {
        case e: NumberFormatException => None
    }
}        
復制代碼

  此時你就可以使用不同的方法來調用toInt方法  

println(toInt("1").getOrElse(0)) // 1
println(toInt("a").getOrElse(0)) // 0

  另外一種使用方法就是使用匹配表達式  

toInt(aString) match {
    case Some(n) => println(n)
    case None => println("Boom! That wasn't a number.")
}

  也可以使用如下直接提取出值 

val result = toInt(aString) match {
    case Some(x) => x
    case None => 0 
}

  2.2 數字類型間的轉化

  1. 問題描述

  你想要從一種數字類型轉化為另一種數字類型,如從Int到Double。

  2. 解決方案

  不同於Java使用cast方法,Scala中可以直接使用數字類型提供的to*方法。

  

  3. 討論

  在Java中,需要強制轉化來將double類型轉化為int類型 

int a = (int) 100.00;

  但是在Scala中,使用to*方法即可完成上述轉化,如果你想要避免轉化錯誤,你可以使用isValid方法來測試是否可以轉化

  

  2.3 重寫默認類型

  1. 問題描述

  當你給變量賦值時,Scala會自動給變量賦予相應的類型,當你創建數字字段時,你需要重寫默認的類型。

  2. 解決方案

  如果你將1賦值給變量a,那么a默認為Int類型

  

  下面例子重寫了默認類型

  

  另一種方法是用類型注釋變量

  

  也可以在等號左邊進行定義

  

  你也可以在數字前面添加0x或0X來創建十六進制整形

  

  3. 討論

  當創建對象實例時,應該注意如下語法結構

var [name]:[Type] = [initial value]

  在初始化數字類型的var字段時,可以使用占位符,其值默認為0,占位符僅僅只在類定義時有效,其他時候則不行,如在方法內部定義不起作用

class Foo {
    var a: Short = 0 // 定義初始值
    var b: Short = _ // 默認為0
}

  但在方法中,可以使用如下方法  

var name = null.asInstanceOf[String]

  當然更好的辦法是使用Option/None/Some模式匹配,這樣可以避免空值

  2.4 替換++、--

  1. 問題描述

  在其他語言中,你可以使用++、--來增1、減1,然而,在Scala中沒有++、--操作符

  2. 解決方案

  由於val類型變量是不可變的,所以不能進行加法或減法的操作,但是var類型是可變,可以使用+=、-=方法來進行加法或減法

  

  同理,也可以使用*=、/=方法進行乘法、除法操作

  

  值得注意的是+=、-=、*=、/=都不是操作符,而是方法,他們是var型Int變量上實現的方法。

  3. 討論

  在其他數字類型上也可以使用+=、-=、*=、/=方法

  

  2.5 比較浮點數

  1. 問題描述

  你需要比較兩個浮點數,但在其他一些編程語言中,它們應該是相等的兩個浮點數

  2. 解決方案

  在Java和許多其他語言,你可以通過創建一個指定比較精度的方法來決這個問題,下面是約等於方法  

def ~=(x: Double, y: Double, precision: Double) = {
    if ((x - y).abs < precision) true else false
}

  

  3. 討論

  當進行浮點數計算時,0.1 + 0.1等於0.2,但是0.1 + 0.2不等於0.3

  

  這種細小的錯誤使得比較兩個浮點數成為真正的問題。

  

  因此,你需要自定義比較精度的函數來比較兩個浮點數是否相等,你可以定義隱式轉化,然后在需要是引入即可。或者將方法放在object對象中,這樣可以直接調用  

object MathUtils {
    def ~=(x: Double, y: Double, precision: Double) = {
        if ((x - y).abs < precision) true else false
}

  然后直接通過MathUtils調用~=方法進行比較 

println(MathUtils.~=(a, b, 0.000001))

  2.6 處理大數

  1. 問題描述

  你正在編寫需要使用非常大的整數或十進制數的應用程序

  2. 解決方案

  你可以使用BigInt或BigDecimal類

  

  不同於其在Java的對應類,這些類支持所有你使用數字類型的操作符

  

  你也可以把它們轉化為其他數字類型

  

  為了避免錯誤,也可以在轉化之前進行測試

  

  3. 討論

  雖然Scala中的BigInt和BigDecimal是由Java中的BigInt和BigDecimal支持的,但是Scala中的類使用更為簡便,並且它們是可變的,可以像其他數字類型一樣操作。

  2.7 生成隨機數

  1. 問題描述

  你需要創建隨機數,如測試應用程序、執行模擬以及許多其他情況

  2. 解決方案

  使用scala.util.Random來創建隨機數

  

  你可以指定隨機生成數字的最大值

  

  上述示例將會生成[0-99]之間的數字,你也可以生成隨機Float(0.0到1.0之間的浮點數)

  

  也可以生成隨機Double(0.0到1.0之間的浮點數)

  

  你也可以在創建Random時指定seed值,也可以之后調用setSeed方法進行設置

  

  3. 討論

  Random類可以應對所有通常的使用,包括生成數字、設置最大值、設置seed值,也可以生成隨機字符

  

  Scala可以生成一段隨機長度的數字,在測試時非常有用

  

  也可以生成隨機長度的浮點數

  

  2.8 創建數字范圍,列表或數組

  1. 問題描述

  你需要創建一個數字范圍、列表或數組,如for循環或用於測試目的

  2. 解決方案

  使用Int類的方法來創建一個數字Range

  

  也可以自定義間距

  

  3. 討論

  在Scala中可以很輕易的創建數字范圍,並且可以很輕易的將其轉化為列表或者數組類型

  

  更好的方式如下

  

  2.9 格式化數字和貨幣

  1. 問題描述

  你想要格式化數字和貨幣來控制小數點和逗號,特別是用於打印輸出。

  2. 解決方案

  對於簡單的數字格式化,可以采用前篇博文提到的f字符串插值

  

  添加逗號的一種簡單方法是調用java.text.NumberFormat類的getIntegerInstance方法

  

  在使用getIntegerInstance方法的時候可以指定地區

  

  在處理浮點數時可以使用getInstance方法

  

  對於貨幣格式,可以使用getCurrencyInstance方法

  

  下面方法可以處理國際化貨幣

  

  3. 討論

  主要討論了使用Java的相關類來格式化數字和貨幣,也可以使用BigDecimal來處理貨幣的格式問題。

三、總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM